我正在寻找一种有效的解决方案来确定一手牌是否是印度拉米纸牌中的获胜手牌。印度拉米纸牌在混合方面与金罗米纸牌类似。人们可以融合相同花色的序列(顺子)或融合一组相同的值。序列和集合都应至少包含 3 张牌。与金罗米牌不同,印度拉米牌一手牌由 13 张牌组成。一手获胜牌应包含至少两个序列,并且这些序列中至少一个必须是纯序列。纯粹,我的意思是该序列不应该在小丑(通配符)的帮助下制作。手牌的其余部分可以由带有或不带有小丑的序列和集合组成。注意:除了一副牌中的 2 张王牌(52 + 2)外,牌组中还有一张随机牌用作王牌。例如,如果随机选择黑桃 5 作为小丑,则牌组中其他花色的剩余 3 个 5 可以用作 2 个常规小丑之上的小丑。
以下是一些不使用小丑的有效获胜手牌的示例:
- A,K,Q,J(黑桃)|2,3,4(红心)|2,2,2(黑桃,梅花,方块)|3,4,5(方块)
- A,K,Q,J,10(黑桃)|4,5,6,7,8(梅花)|9,9,9(方块,梅花,黑桃)
- A,K,Q,J,10,9,8,7,6,5(黑桃)|4,3,2(黑桃)
以下是一些使用小丑赢得牌局的例子。假设 6(黑桃)是从牌堆中随机挑选的小丑;所以剩下的所有 6 都可以用作小丑。
- A,K,Q,J(黑桃;纯序列)|7,7,7(方块,梅花,黑桃)|3,3,6(方块,梅花,梅花;与百搭组合)|A,2,6(俱乐部,俱乐部,红心)
- A,2,3(红桃)|4,5,6(红桃)|7,7,7,7(黑桃,梅花,方块,红桃)|8,6,10,小丑(黑桃,方块,黑桃;序列与小丑、6 和普通小丑)
以下是一些示例:NOT获胜的一手牌:
- A,2,Joker(红心)|4,5,Joker(红心)|7,7,7,7(所有花色)|9,9,9(梅花,方块,红心)(这不是有效牌,因为它不包含纯序列)
- A,2,3,4(红心)|7,7,7(梅花,钻石,红心)|8,8,8(梅花,钻石,红心)|9,9,9(梅花,钻石,红心) (这是无效的,因为它不包含第二个序列)
我希望这已经解释了什么是获胜牌。下面的模型代表一张卡:
public class Card {
public final static int SPADES = 0,
HEARTS = 1,
DIAMONDS = 2,
CLUBS = 3;
public final static int ACE = 1,
JACK = 11,
QUEEN = 12,
KING = 13,
JOKER = 0;
private final int suit;
private final int value;
public Card(int theValue, int theSuit) {
value = theValue;
suit = theSuit;
}
public int getSuit() {
return suit;
}
public int getValue() {
return value;
}
public String getSuitAsString() {
switch ( suit ) {
case SPADES: return "Spades";
case HEARTS: return "Hearts";
case DIAMONDS: return "Diamonds";
case CLUBS: return "Clubs";
default: return "??";
}
}
public String getValueAsString() {
switch ( value ) {
case 1: return "Ace";
case 2: return "2";
case 3: return "3";
case 4: return "4";
case 5: return "5";
case 6: return "6";
case 7: return "7";
case 8: return "8";
case 9: return "9";
case 10: return "10";
case 11: return "Jack";
case 12: return "Queen";
case 13: return "King";
default: return "JOKER";
}
}
@Override
public String toString() {
return getValueAsString().equals("JOKER") ? "JOKER" : getValueAsString() + "(" + getSuitAsString() + ")";
}
@Override
public boolean equals(Object card) {
return suit == ((Card) card).getSuit() && value == ((Card) card).getValue();
}
}
我还编写了一些函数来获取卡中可能的序列和集合。 getSequences 函数中的参数 (List) 已按花色排序,然后按值排序。对于 getSets 函数中的参数,卡片仅按值排序。两个函数中第二个参数 (min) 的值为 3。
private List<List<Card>> getSequences(List<Card> hand, int min) {
List<List<Card>> sequences = new ArrayList<>();
List<Card> sequence = new ArrayList<>();
for(int i=1; i<hand.size(); i++) {
if(hand.get(i).getSuit() == hand.get(i-1).getSuit() &&
(hand.get(i).getValue() - hand.get(i-1).getValue()) == 1) {
sequence.add(hand.get(i-1));
if(hand.get(i).getValue() == 13) {
int j = i;
while(hand.get(j).getSuit() == hand.get(i).getSuit()) {
j--;
if(hand.get(j).getValue() == 1) {
sequence.add(hand.get(j));
}
}
}
if(i == hand.size() -1) {
sequence.add(hand.get(i));
sequences.add(sequence);
}
} else {
sequence.add(hand.get(i-1));
if(sequence.size() >= min) {
sequences.add(sequence);
}
sequence = new ArrayList<>();
}
}
return sequences;
}
private List<List<Card>> getSets(List<Card> hand, int min) {
List<List<Card>> sets = new ArrayList<>();
List<Card> set = new ArrayList<>();
for(int i=1; i<hand.size(); i++) {
if(hand.get(i).getValue() != joker.getValue()) {
if(hand.get(i).getValue() == hand.get(i-1).getValue()) {
set.add(hand.get(i-1));
if(i == hand.size() -1) {
set.add(hand.get(i));
}
} else {
set.add(hand.get(i-1));
if(set.size() >= min) {
sets.add(set);
}
set = new ArrayList<>();
}
}
}
return sets;
}
我不认为这是查找序列和集合的最优雅的方法。因此,我欢迎任何关于如何改进它的建议。但我真正需要帮助的是我下一步该怎么做?集合和序列之间可能存在重叠。例如,如果有以下卡:
- A,2,3(黑桃)|4,4,4(黑桃,梅花,红桃)
我的 getSequences 函数将返回 A,2,3,4(黑桃) 作为序列。我应该避免在我的序列中包含 4 个黑桃,以便将其用于 4 组中。
请提供如何有效确定获胜手牌的建议。
P.S:在判定胜手牌时,玩家手上有14张牌。融合 13 张牌后,第 14 张牌将作为终结牌被丢弃。