Java 确定印度拉米手牌是否是获胜手牌-爪哇
我正在寻找一个有效的解决方案,以确定一手牌是否是印度拉米酒的赢家。印度拉米酒和杜松子拉米酒在融合方面很相似。一个人可以将同一套衣服的序列(直线)融合在一起,也可以将一组相同的值融合在一起。序列和集合应至少包含3张卡。与杜松子酒不同,在印度拉米酒中,一手牌由13张牌组成。获胜的手牌应至少包含两个序列,且其中至少一个序列必须是纯序列。我所说的纯,是指序列不应该在小丑(外卡)的帮助下进行。手的其余部分可以由有或没有小丑的序列和场景组成。注:除了一副牌(52+2)中的两张小丑牌外,还有一张随机牌用作小丑牌。例如,如果随机挑选了5个黑桃作为小丑,那么甲板上其余3个5的其他套装可以作为2个普通小丑的小丑 以下是一些不使用小丑的有效赢牌示例:Java 确定印度拉米手牌是否是获胜手牌-爪哇,java,Java,我正在寻找一个有效的解决方案,以确定一手牌是否是印度拉米酒的赢家。印度拉米酒和杜松子拉米酒在融合方面很相似。一个人可以将同一套衣服的序列(直线)融合在一起,也可以将一组相同的值融合在一起。序列和集合应至少包含3张卡。与杜松子酒不同,在印度拉米酒中,一手牌由13张牌组成。获胜的手牌应至少包含两个序列,且其中至少一个序列必须是纯序列。我所说的纯,是指序列不应该在小丑(外卡)的帮助下进行。手的其余部分可以由有或没有小丑的序列和场景组成。注:除了一副牌(52+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(黑桃)
- A、 K,Q,J(黑桃;纯序列)| 7,7,7(钻石,棍棒,黑桃)| 3,3,6(钻石,棍棒,棍棒;与小丑一起设定)| A,2,6(棍棒,棍棒,红桃)
- A、 2,3(红桃)| 4,5,6(红桃)| 7,7,7(黑桃,梅花,钻石,红桃)| 8,6,10,小丑(黑桃,钻石,黑桃;与小丑的顺序,6和普通小丑)
- A、 2,小丑(红桃)| 4,5,小丑(红桃)| 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函数中的参数(列表)已按suit排序,然后按值排序。对于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;
}
private List-getSequences(List-hand,int-min){
列表序列=新的ArrayList();
列表序列=新的ArrayList();
对于(int i=1;i=min){
顺序。添加(顺序);
}
序列=新的ArrayList();
}
}
返回序列;
}
私有列表getset(列表手,int-min){
列表集=新的ArrayList();
列表集=新的ArrayList();
对于(int i=1;i=min){
集合。添加(集合);
}
set=newarraylist();
}
}
}
返回集;
}
我不认为这是寻找序列和集合的最优雅的方式。因此,我欢迎任何关于如何改进的建议。但我真正需要帮助的是我下一步该做什么?集合和序列之间可能存在重叠。例如,在以下卡的情况下:
- A、 2,3(黑桃)| 4,4,4(黑桃、梅花、红桃) 我的getSequences函数将返回一个,2,3,4(黑桃)作为序列。我应该避免在我的序列中包含4个黑桃,以便在4个黑桃中使用
附言:在决定胜出一手牌时,玩家手中将有14张牌。融合13张牌后,第14张牌将作为结束牌丢弃。我已经实现了一个java版本的Rummikub(一个具有类似约束的游戏) 我的方法是给每张卡一个隐藏的整数属性(一个素数) 然后,每个有效的meld可以唯一地表示为一个整数。 当然,可以事先计算出构成有效融合的精确整数,并将其放入
集合中
检查一只手是否只包含有效的混合,然后简化为检查一个给定的long是否可以写成一组给定数字的乘积。(可使用递归和动态规划)
具体示例(1):
- 红桃王牌=>2
- 两颗心=>3
- 三颗红心=>5颗
Set validmels={30,…,…}
如果手(值=60),那么我们知道它包含两个有效的混合
具体示例(2)
- 1个俱乐部=2个
- 2个俱乐部=3个
- 3个俱乐部=5个
- 4个俱乐部=7个
- 4颗红心=179颗
- 4颗钻石=181
已知有效的MELD={30,210,226793,…}
手的价值=6803790
简单(递归)算法:
6803790可被30整除
(6803790/30=)226793可被226793整除
递归算法得出结论,这是一个有效的分支
备选方案
6803790可被210整除
(6803790/210)=32399不能被任何有效的meld数整除
递归算法在这里结束分支
如果您需要能够处理手牌的某些部分并不总是有效meld的一部分的情况,您可能希望研究一下
在这个游戏中,手牌总是在14张牌上评估,还是玩家可以有不同数量的牌?总是在14张牌上评估!在你的例子中,你说A,K,Q,J(黑桃)| 2,3,4(红桃)| 2,2,2(黑桃,梅花,钻石)| A,2,3(钻石)
是赢的一手牌。我看到2吨