集合综合案例:斗地主

按照斗地主的规则,完成洗牌发牌的动作。

具体规则

  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 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值