Java實現鬥地主實例


前些天我實現了發紅包案例:Java實現微信、QQ等羣主發紅包實例(普通紅包)

Java實現微信、QQ等羣主發紅包實例(拼手氣紅包)

今天繼續來實現生活中一些有趣的案例:鬥地主


分析:

首先,我們來梳理一下規則:

  1. 準備牌階段:鬥地主一般用一副牌,有54張,其中有大王小王各1張,其他52張牌,分別是4個花色,每種花色13張。四種花色分別爲♥ ♦ ♠ ♣,定義一個集合來存儲它們;而每一種花色中的13張牌爲:(由大到小)2 A K Q J 10 9 8 7 6 5 4 3,也定義一個集合來存儲它們。遍歷這兩個集合,可以組裝成爲52張牌,例如♣7 ♥A
  2. 洗牌階段:使用集合工具類Collections方法,其中static void shuffle(List<?> list)使用指定的隨機數對指定列表進行置換,會隨機的打亂集合中的元素的順序
  3. 發牌階段:要求每一位玩家擁有17張牌,剩餘三張作爲底牌,一人一張輪流發牌:集合的索引(0-53)%3,定義4個集合,來存儲3個玩家的牌和場上的底牌。索引%3,有三個值(0,1,2)0%3=01%3=12%3=23%3=0,當索引>=51時,改爲發底牌
  4. 看牌階段:直接打印集合,遍歷存儲玩家和底牌的集合


實現:

public class Poker {
    public static void main(String[] args) {
        // 創建牌盒集合來存儲牌面
        ArrayList<String> pokerBox = new ArrayList<String>();
        // 創建花色集合
        ArrayList<String> colors = new ArrayList<String>();

        // 創建數字集合
        ArrayList<String> numbers = new ArrayList<String>();

        // 給花色集合加入花色
        colors.add("♥");
        colors.add("♦");
        colors.add("♠");
        colors.add("♣");

        // 由小到大加入牌的點數
        for(int i = 2;i <= 10;i++){
            numbers.add(i+"");
        }
        numbers.add("J");
        numbers.add("Q");
        numbers.add("K");
        numbers.add("A");
        
        // 拿出每一個花色然後跟每一個點數進行結合,然後存儲到牌盒中
        for (String color : colors) {
            // color每一個花色 
            // 遍歷數字集合
            for(String number : numbers){
                // 結合
                String card = color+number;
                // 存儲到牌盒中
                pokerBox.add(card);
            }
        }

        // 添加大王小王
        pokerBox.add("小王");
        pokerBox.add("大王");	  
       
        // 洗牌將牌盒中牌的索引打亂 
        Collections.shuffle(pokerBox);
        
        // 創建三個玩家集合,創建一個底牌集合
        ArrayList<String> player1 = new ArrayList<String>();
        ArrayList<String> player2 = new ArrayList<String>();
        ArrayList<String> player3 = new ArrayList<String>();
        ArrayList<String> dipai = new ArrayList<String>();	  

        // 遍歷牌盒   
        for(int i = 0;i < pokerBox.size();i++){
            // 獲取牌面
            String card = pokerBox.get(i);
            // 分別按照索引存儲分配牌
            if(i>=51){
                dipai.add(card);
            } else if(i%3==0){
                player1.add(card);
            }else if(i%3==1){
               	player2.add(card);
            }else{
              	player3.add(card);
            }
        }
        
        // 輸出結果
        System.out.println("玩家1:"+player1);
        System.out.println("玩家2:"+player2);
        System.out.println("玩家3:"+player3);
        System.out.println("底牌:"+dipai);  
	}
}

結果展示:


改進方案:

鬥地主的玩家的牌並不是按照順序來排列的,看牌的時候十分難受。

將存牌的時候加入Map集合,形成鍵值對,使得牌的索引和組裝好的牌形成配對,從牌的大小來存放,然後使用Collections中的方法soft(List)來打亂索引順序,最後發牌,看牌使用查表方法,遍歷玩家和底牌集合,獲取到Map集合的key,通過key找到value值。


實現:

public class Doudizhu{
    public static void main(String[] args) {
        // 創建一個Map集合,存儲牌的索引和組裝好的牌
        HashMap<Integer,String> poker = new HashMap<>();

        // 創建一個list集合,存儲牌的索引
        ArrayList<Integer> pokerIndex = new ArrayList<>();

        // 定義兩個集合,存儲牌的花色和序號
        List<String> colors = List.of("♠","♣","♦","♥");
        List<String> numbers = List.of("2","A","K","Q","J","10","9","8","7","6","5","4","3");

        // 把大王小王存到集合中
        int index = 0;
        poker.put(index,"大王");
        pokerIndex.add(index);
        index++;
        poker.put(index,"小王");
        pokerIndex.add(index);
        index++;

        // 循環嵌套兩個集合,組裝這52張牌,存儲到集合中去
        for (String number : numbers){
            for (String color : colors){
                poker.put(index,color+number);
                pokerIndex.add(index);
                index++;
            }
        }

        // 輸出查看結果
        System.out.println(poker);
        System.out.println(pokerIndex);

        // 洗牌階段
        Collections.shuffle(pokerIndex);

        // 發牌階段
        ArrayList<Integer> player01 = new ArrayList<>();
        ArrayList<Integer> player02 = new ArrayList<>();
        ArrayList<Integer> player03 = new ArrayList<>();
        ArrayList<Integer> dipai = new ArrayList<>();

        // 遍歷存儲牌索引的list集合,獲取每一個牌的索引
        for (int i = 0; i < pokerIndex.size(); i++) {
            Integer in = pokerIndex.get(i);
            // 先判斷底牌
            if(i >= 51){
                dipai.add(in);
            }else if(i % 3 == 0){
                player01.add(in);
            }else if(i % 3 == 1){
                player02.add(in);
            }else if(i % 3 == 2){
                player03.add(in);
            }
        }

        // 排序:使用Collections中的方法sort(List)
        Collections.sort(player01);
        Collections.sort(player02);
        Collections.sort(player03);
        Collections.sort(dipai);

        // 調用看牌的方法
        lookPoker("玩家1" , poker , player01);
        lookPoker("玩家2" , poker , player02);
        lookPoker("玩家3" , poker , player03);
        lookPoker("底牌" , poker , dipai);

    }

    public static  void lookPoker(String name,HashMap<Integer,String> poker,ArrayList<Integer> list){
        // 輸出玩家的名稱
        System.out.print(name + ": ");
        // 遍歷玩家或底牌集合,獲取牌的索引
        for(Integer key : list){
            // 使用牌的索引,去Map集合中,找到對應的牌
            String value = poker.get(key);
            System.out.print(value + " ");
        }
        System.out.println();
    }
}

結果展示:

兩次打印輸出的內容不一樣,但結果都能按照從大到小的順序輸出,使查看效果和現實中的鬥地主一樣!

 

       感謝您的閱讀,不足之處歡迎指正!

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章