美文网首页
[Java]01.实现斗地主洗牌和发牌

[Java]01.实现斗地主洗牌和发牌

作者: NiceBen | 来源:发表于2021-09-06 16:25 被阅读0次

    简介

    说明:斗地主是全国范围内的一种桌面游戏,尽管全国各种类型,但大同小异。本节我们先来实现一下斗地主中的简单洗牌、发牌和看牌功能。

    规则:按照斗地主的规则,完成洗牌发牌的动作。具体规则为使用 54 张牌打乱顺序,3 个玩家参与游戏,3 人交替摸牌,每人 17 张牌,后 3 张留作底牌。

    实现思路:

    1. 准备牌:通过 List<Poker> 进行存储
    2. 洗牌:通过 Collections#shuffle 方法,将集合进行打乱
    3. 发牌:通过 Stream 将每个人手中的牌排序,并进行打印
    4. 看牌:将每个人手中的牌输出

    实现代码

    1. 定义类扑克类型的枚举类,通过枚举可以限定出现的元素
    public enum PokerTypeEnum {
        
        red_Heart("红桃"),
        black_Heart("黑桃"),
        red_Card("方片"),
        black_Card("梅花"),
        big_Joker("大王"),
        small_Joker("小王");
    
        private String type;
    
        PokerTypeEnum(String type) {
            this.type = type;
        }
    
        public String getType() {
            return type;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    }
    
    1. 定义类扑克数字的枚举类
    public enum PokerValueEnum {
    
        value_0(""),
        value_1("A"),
        value_2("2"),
        value_3("3"),
        value_4("4"),
        value_5("5"),
        value_6("6"),
        value_7("7"),
        value_8("8"),
        value_9("9"),
        value_10("10"),
        value_11("J"),
        value_12("Q"),
        value_13("K");
    
        private String value;
    
        PokerValueEnum(String value) {
            this.value = value;
        }
    
        public String getValue() {
            return value;
        }
    
        public void setValue(String value) {
            this.value = value;
        }
    }
    
    1. 定义一个扑克的实体类,用来记录一张扑克
    public class Poker {
    
        // 类型
        private PokerTypeEnum type;
    
        // 值
        private PokerValueEnum value;
    
        // 顺序
        private Integer order;
    
        public Poker() {
        }
    
        public Poker(PokerTypeEnum type, PokerValueEnum value, Integer order) {
            this.type = type;
            this.value = value;
            this.order = order;
        }
    
        public PokerTypeEnum getType() {
            return type;
        }
    
        public void setType(PokerTypeEnum type) {
            this.type = type;
        }
    
        public PokerValueEnum getValue() {
            return value;
        }
    
        public void setValue(PokerValueEnum value) {
            this.value = value;
        }
    
        public Integer getOrder() {
            return order;
        }
    
        public void setOrder(Integer order) {
            this.order = order;
        }
    }
    
    1. 创建扑克的工厂类,用于生成一副扑克,这里返回的是 新生成的 List,但是内部的每个扑克实体类是共享的,模仿象棋的享元模式,在多用户下,减少内存消耗。对于每张扑克来说,所有的实例都是一样的不会发生变化,每个实例针对自己新获取的扑克集合进行操作。
    public class PokerUtil {
    
        private static List<Poker> pokers = new ArrayList<>();
    
        public static void main(String[] args) {
            initPokers();
            System.out.println(pokers.size());
        }
    
        public synchronized static List<Poker> getPokers() {
            if (CollectionUtils.isEmpty(pokers)) {
                initPokers();
            }
            return new ArrayList<>(pokers);
        }
    
        private static void initPokers() {
            PokerTypeEnum[] types = PokerTypeEnum.values();
            PokerValueEnum[] values = PokerValueEnum.values();
    
            // add common cards
            int pokerIndex = 1;
            for (PokerValueEnum valueEnum : values) {
                if (PokerValueEnum.value_0 != valueEnum) {
                    for (PokerTypeEnum typeEnum : types) {
                        if (PokerTypeEnum.big_Joker != typeEnum && PokerTypeEnum.small_Joker != typeEnum) {
                            Poker poker = new Poker();
                            poker.setType(typeEnum);
                            poker.setValue(valueEnum);
                            poker.setOrder(pokerIndex++);
                            pokers.add(poker);
                        }
                    }
                }
            }
            // add Jokers
            pokers.add(new Poker(PokerTypeEnum.big_Joker, PokerValueEnum.value_0, pokerIndex++));
            pokers.add(new Poker(PokerTypeEnum.small_Joker, PokerValueEnum.value_0, pokerIndex));
        }
    }
    
    1. 该类是每个用户的实体类,创建了 3 个玩家,以及一个底牌。每桌用户生成一个对应的实体类。
    public class PlayerUtil {
    
        private List<Poker> player1 = new ArrayList<>();
        private List<Poker> player2 = new ArrayList<>();
        private List<Poker> player3 = new ArrayList<>();
        private List<Poker> holeCards = new ArrayList<>();
    
        // 创建一个比较器
        private static Comparator<Poker> comparator = Comparator.comparing(Poker::getOrder);
    
        public void beginGame() {
            shuffleAndTakePokers();
            viewPlayerHandPokers();
        }
    
        private void viewPlayerHandPokers() {
            pushBoss();
            check(player1, "player1");
            check(player2, "player2");
            check(player3, "player3");
            check(holeCards, "holeCards");
        }
    
        private void check(List<Poker> playerPokers, String playerName) {
            // view hand poker
            System.out.print(playerName + ": [");
            playerPokers.stream().sorted(comparator).forEach(poker -> System.out.print(poker.getType().getType() + poker.getValue().getValue() + "\t"));
            System.out.println("]");
        }
    
        private void pushBoss() {
            List<String> playerNames = Arrays.asList("player1", "player2", "player3");
            Random r = new Random();
            int bossIndex = r.nextInt(3);
            String boss = playerNames.get(bossIndex);
            System.out.println("此局地主是 : " + boss);
        }
    
        private void shuffleAndTakePokers() {
            List<Poker> privatePoker = PokerUtil.getPokers();
            // shuffle
            Collections.shuffle(privatePoker);
            clearPlayerHandPokers();
            // take
            for (int i = 0; i < privatePoker.size(); i++) {
                if (i >= privatePoker.size() - 3) {
                    holeCards.add(privatePoker.get(i));
                } else if (i % 3 == 0) {
                    player1.add(privatePoker.get(i));
                } else if (i % 3 == 2) {
                    player2.add(privatePoker.get(i));
                } else {
                    player3.add(privatePoker.get(i));
                }
            }
        }
    
        private void clearPlayerHandPokers() {
            player1.clear();
            player2.clear();
            player3.clear();
            holeCards.clear();
        }
    }
    
    1. 通过外部的来创建 玩家与一副扑克,进行游戏。
    public class MainTest {
    
        public static void main(String[] args) {
            PlayerUtil playerUtil = new PlayerUtil();
            playerUtil.beginGame();
        }
    }
    

    打印输出结果:


    image-20210906160556748.png

    相关文章

      网友评论

          本文标题:[Java]01.实现斗地主洗牌和发牌

          本文链接:https://www.haomeiwen.com/subject/dbzewltx.html