集合綜合案例:鬥地主

按照鬥地主的規則,完成洗牌發牌的動作。

具體規則

  1. 組裝54張撲克牌將
  2. 54張牌順序打亂
  3. 三個玩家參與遊戲,三人交替摸牌,每人17張牌,最後三張留作底牌。
  4. 查看三人各自手中的牌(按照牌的大小排序)、底牌

規則:手中撲克牌從大到小的擺放順序:大王,小王,2,A,K,Q,J,10,9,8,7,6,5,4,3

需求分析

  1. 準備牌:

完成數字與紙牌的映射關係:

使用雙列Map(HashMap)集合,完成一個數字與字符串紙牌的對應關係(相當於一個字典)。

  1. 洗牌:

通過數字完成洗牌發牌

  1. 發牌:

將每個人以及底牌設計爲ArrayList,將最後3張牌直接存放於底牌,剩餘牌通過對3取模依次發牌。

存放的過程中要求數字大小與鬥地主規則的大小對應。

將代表不同紙牌的數字分配給不同的玩家與底牌。

  1. 看牌:

通過Map集合找到對應字符展示。

通過查詢紙牌與數字的對應關係,由數字轉成紙牌字符串再進行展示。

普通版:手牌無序

package cn.luis;

import java.util.*;

/**
 * @ClassName Dou
 * @Description TODO 鬥地主綜合案例:準備牌、洗牌、看牌
 * @Author L
 * @Date 2020.06.13 10:01
 * @Version 1.0
 * @Remark :初級版本,牌的順序混亂
 **/
public class Dou {
    public static void main(String[] args) {
        // 準備好的牌:poker
        ArrayList<String> poker = readyPai();
        // 洗好的牌:poker
        ArrayList<String> poker2 = xiPai(poker);
        // 發牌
        Map<String, ArrayList<String>> map = faPai(poker2);
        // 看牌
        showPai(map);
    }

    /**
     * 準備牌
     */
    public static ArrayList<String> readyPai(){
        ArrayList<String> poker = new ArrayList<>();
        // 定義兩個數組,存儲牌的花色和牌的序號
        String[] colors = {"♠","♥","♣","♦"};
        String[] nums = {"2","A","K","Q","J","10","9","8","7","6","5","4","3"};
        // 先把大王和小王存儲到撲克牌集合中
        poker.add("大王");
        poker.add("小王");
        // 循環嵌套遍歷兩個數組,組裝52張撲克牌
        for (String color : colors) {  // colors.for 先循環顏色的運行快
            for (String num : nums) {
                // 把組裝好的牌存儲到poker集合中
                poker.add(color + num);
            }
        }
        // 查看組裝是否成功
        // System.out.println(poker);
        return poker;
    }

    /**
     * 洗牌
     * @param poker
     */
    public static ArrayList<String> xiPai(ArrayList<String> poker){
        // 使用Collections工具類的方法將集合元素順序打亂
        Collections.shuffle(poker);
        return poker;
    }

    /**
     * 發牌
     * @param poker
     * @return
     */
    public static Map<String,ArrayList<String>> faPai(ArrayList<String> poker){
        // 定義四個集合,存儲玩家的牌和底牌
        ArrayList<String> player01 = new ArrayList<>();
        ArrayList<String> player02 = new ArrayList<>();
        ArrayList<String> player03 = new ArrayList<>();
        ArrayList<String> diPai = new ArrayList<>();
        // 用來存儲上面四個集合
        Map<String,ArrayList<String>> map = new LinkedHashMap<>();

        /*
           遍歷poker集合,獲取每一張牌
           爲三位玩家輪流發牌:使用poker集合的 (索引 % 3)
           剩餘三張給底牌
           注意:
                先判斷底牌:索引 >= 51,否則就發沒了
         */
        for (int i = 0; i < poker.size(); i++) {
            // 獲取每一張牌
            String p = poker.get(i);
            // 輪流發牌
            if (i >= 51) {
                // 給底牌發牌
                diPai.add(p);
            } else if (i % 3 == 0) {
                // 給玩家一發牌
                player01.add(p);
            } else if (i % 3 == 1) {
                // 給玩家一發牌
                player02.add(p);
            } else if (i % 3 == 2) {
                // 給玩家一發牌
                player03.add(p);
            }
        }
        // 將存儲牌的集合裝入map集合
            map.put("player01",player02);
            map.put("player02",player02);
            map.put("player03",player03);
            map.put("diPai",diPai);
        return map;
    }

    /**
     * 看牌
     * @param map
     */
    public static void showPai(Map<String,ArrayList<String>> map){
        Set<String> set = map.keySet();

        // 遍歷鍵找值方式
        System.out.println("======迭代器======");
        Iterator<String> it = set.iterator();
        while (it.hasNext()){
            String key = it.next();
            ArrayList<String> list = map.get(key);
            System.out.println(key+":"+list);
        }
        System.out.println("======增強for======");
        for (String key : set) {
            ArrayList<String> list = map.get(key);
            System.out.println(key+":"+list);
        }
        System.out.println("======增強for======");
        for (String key : map.keySet()) {
            ArrayList<String> list = map.get(key);
            System.out.println(key+":"+list);
        }
        // 遍歷鍵值對方式
        Set<Map.Entry<String, ArrayList<String>>> set2 = map.entrySet();
        System.out.println("======迭代器======");
        Iterator<Map.Entry<String, ArrayList<String>>> it2 = set2.iterator();
        while (it2.hasNext()){
            Map.Entry<String, ArrayList<String>> entry = it2.next();
            String key = entry.getKey();
            ArrayList<String> value = entry.getValue();
            System.out.println(key+ "=" +value);
        }
        System.out.println("======增強for======");
        for (Map.Entry<String, ArrayList<String>> entry : set2) {
            String key = entry.getKey();
            ArrayList<String> value = entry.getValue();
            System.out.println(key+ "=" +value);
        }
    }
}

結果:

player01:[♥10, ♣4, ♠6, ♥K, ♣J, ♠K, ♥Q, ♠Q, ♦Q, ♠8, ♦2, ♦J, ♠3, ♥7, ♠9, 大王, ♠J]
player02:[♥10, ♣4, ♠6, ♥K, ♣J, ♠K, ♥Q, ♠Q, ♦Q, ♠8, ♦2, ♦J, ♠3, ♥7, ♠9, 大王, ♠J]
player03:[♣9, ♦5, ♣3, ♦A, ♣10, ♠2, ♣8, ♣A, ♠A, ♥A, ♣5, ♥6, ♥2, ♣2, ♠7, 小王, ♥8]
diPai:[♦10, ♣7, ♥5]

進階版:手牌有序,結構優化

package cn.luis;

import java.util.*;

/**
 * @ClassName DouPro
 * @Description TODO 鬥地主綜合案例:準備牌、洗牌、看牌
 * @Author L
 * @Date 2020.06.13 10:01
 * @Version 2.0
 * @Remark :高級版,對牌的順序進行完善
 **/
public class DouPro {
    public static void main(String[] args) {
        Map<String, ArrayList<Integer>> pai = faPai("鋼鐵俠", "蜘蛛俠", "小飛俠", xiPai());
        showPai(pai, readyPai());
    }

    /**
     * 準備牌
     */
    public static Map<Integer, String> readyPai() {
        // 創建牌的花色和數字集合
        List<String> colors = List.of("♠", "♥", "♣", "♦");
        List<String> nums = List.of("2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3");
        // 存儲牌的集合
        Map<Integer, String> poker = new HashMap<>();

        // 組裝牌
        poker.put(0, "大王");
        poker.put(1, "小王");
        int index = 2;
        for (String num : nums) { // 比color在前循環更浪費時間
            for (String color : colors) {
                String s = color + num;
                poker.put(index, s);
                index++;
            }
        }
        // System.out.println(poker);
        return poker;
    }

    /**
     * 洗牌
     * 創建集合:存取牌的序號,方便發牌調用
     *
     * @return
     */
    public static ArrayList<Integer> xiPai() {
        // 存取牌的序號(和map集合的key相同)
        ArrayList<Integer> pid = new ArrayList<>();
        for (int i = 0; i < 54; i++) {
            pid.add(i);
        }
        Collections.shuffle(pid);
        //System.out.println(pid);
        return pid;
    }

    /**
     * 發牌
     *
     * @param name1
     * @param name2
     * @param name3
     * @param list
     * @return
     */
    public static Map<String, ArrayList<Integer>> faPai(String name1, String name2, String name3, ArrayList<Integer> list) {
        // 定義四個集合,存儲撲克牌集合的key
        ArrayList<Integer> player01 = new ArrayList<>();
        ArrayList<Integer> player02 = new ArrayList<>();
        ArrayList<Integer> player03 = new ArrayList<>();
        ArrayList<Integer> diPai = new ArrayList<>();

        // 分發牌
        // 遍歷list,用map.get方法獲取value
        for (int i = 0; i < list.size(); i++) {
            Integer id = list.get(i);
            // 先判斷底牌
            if (i >= 51) {
                diPai.add(id);
            } else if (i % 3 == 0) {
                player01.add(id);
            } else if (i % 3 == 1) {
                player02.add(id);
            } else if (i % 3 == 2) {
                player03.add(id);
            }
        }
        Map<String, ArrayList<Integer>> map = new LinkedHashMap<>();
        map.put(name1, player01);
        map.put(name2, player02);
        map.put(name3, player03);
        map.put("底牌", diPai);
        return map;
    }

    /**
     * 看牌
     *
     * @param p     :發牌方法傳遞過來的
     * @param poker :準備牌方法傳遞過來的
     */
    public static void showPai(Map<String, ArrayList<Integer>> p, Map<Integer, String> poker) {
        Set<String> set = p.keySet();
        // 遍歷發牌集合
        for (String name : set) {
            System.out.print(name + ": ");
            ArrayList<Integer> list = p.get(name);

            // 排序(發牌集合中的ArrayList集合)
            Collections.sort(list);

            // 根據list集合的元素遍歷map集合中的value
            for (int index = 0; index < list.size(); index++) {
                Integer value = list.get(index);
                String pai = poker.get(value);
                System.out.print(pai + " ");
            }
            System.out.println();
        }
    }
}

結果:

鋼鐵俠: 小王 ♥2 ♦2 ♥A ♦A ♣K ♠Q ♥Q ♦Q ♥J ♥9 ♣9 ♠8 ♠7 ♦7 ♠6 ♠4 
蜘蛛俠: 大王 ♠2 ♥K ♠J ♦J ♣10 ♣8 ♦8 ♣6 ♠5 ♣5 ♦5 ♣4 ♦4 ♠3 ♣3 ♦3 
小飛俠: ♣2 ♠A ♣A ♠K ♦K ♣J ♠10 ♥10 ♦10 ♠9 ♦9 ♥8 ♥6 ♦6 ♥5 ♥4 ♥3 
底牌: ♣Q ♥7 ♣7 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章