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

简介

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

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

实现思路:

  1. 准备牌:通过 List 进行存储
  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 pokers = new ArrayList<>();

    public static void main(String[] args) {
        initPokers();
        System.out.println(pokers.size());
    }

    public synchronized static List 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 player1 = new ArrayList<>();
    private List player2 = new ArrayList<>();
    private List player3 = new ArrayList<>();
    private List holeCards = new ArrayList<>();

    // 创建一个比较器
    private static Comparator 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 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 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 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.实现斗地主洗牌和发牌)