简介
说明:斗地主是全国范围内的一种桌面游戏,尽管全国各种类型,但大同小异。本节我们先来实现一下斗地主中的简单洗牌、发牌和看牌功能。
规则:按照斗地主的规则,完成洗牌发牌的动作。具体规则为使用 54 张牌打乱顺序,3 个玩家参与游戏,3 人交替摸牌,每人 17 张牌,后 3 张留作底牌。
实现思路:
- 准备牌:通过 List
进行存储 - 洗牌:通过 Collections#shuffle 方法,将集合进行打乱
- 发牌:通过 Stream 将每个人手中的牌排序,并进行打印
- 看牌:将每个人手中的牌输出
实现代码
- 定义类扑克类型的枚举类,通过枚举可以限定出现的元素
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;
}
}
- 定义类扑克数字的枚举类
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;
}
}
- 定义一个扑克的实体类,用来记录一张扑克
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;
}
}
- 创建扑克的工厂类,用于生成一副扑克,这里返回的是 新生成的 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));
}
}
- 该类是每个用户的实体类,创建了 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();
}
}
- 通过外部的来创建 玩家与一副扑克,进行游戏。
public class MainTest {
public static void main(String[] args) {
PlayerUtil playerUtil = new PlayerUtil();
playerUtil.beginGame();
}
}
打印输出结果: