重来。什么是Card
?它是一个有等级和西装的对象。所以你需要:
- 一套
enum
名为西装。
- 等级的一系列数字。可能是 2 到 14(10,Jack,Queen,King,Ace)。
- 或者一个枚举:两个、三个、...、ACE。那可能有点多。
- 一个
Card
有西装和等级的班级。
Card
不应该有二传手,因为您不希望玩家在拥有一张牌时更换一张牌。所以,
public class Card {
private final Suit suit;
private final int rank;
public Card(final Suit suit, final int rank) {
this.suit = suit;
this.rank = rank;
}
// Getters, toString, equals, hashCode, formatting for humans, etc.
}
现在,您需要构建一个甲板。一副牌应该包含一张卡片列表,并且你必须能够洗牌。您可以将其设为ArrayList<Card>
,但我会将其设为包含此类列表的对象,因为卡片组具有行为。deck.deal()
比做deal
内联的事情更清楚。
public class Deck {
private List<Card> cards = new ArrayList<>();
public Deck() {
for (Suit suit: Suit.values()) {
for (int rank = 2; rank <= ACE; rank ++) {
cards.add(new Card(suit, rank));
}
}
Collections.shuffle(cards); // Perhaps use your own Random too.
}
public synchronized Card deal() {
Card dealt = cards.get(0);
cards.remove(0);
return dealt;
}
}
这里有各种各样的设计决策要做。
- Rank 也应该是一个枚举吗?它使 for 循环更容易。
- 构建甲板应该在
Deck
班级内部吗?假设您不仅要处理扑克和桥牌,还要处理 pinochle 或 bezique,其中每个花色中有 2 个 Ace-9。
- 改组是否应该与加密质量的 RNG 相关联?
- 您应该使用 a
Stack
还是Deque
代替 a ArrayList
? Stack
可能更清楚,而Deque
s 不能被洗牌。
- 你有一张牌面朝上或朝下的想法。那是一个补充。玩纸牌?
- 如果甲板是空的,该怎么
deal
办?这是使用堆栈的一个很好的理由。