对于家庭作业,我获得了一个卡类,其中列举了Rank和Suit的类型。我需要比较两个扑克牌(每手是5张卡的ArrayList
)并决定胜利者。
isStraight()
函数真的很困扰我,因为我必须在Ace之后重新计算。例如,
QUEEN,KING,ACE,TWO,THREE
仍然被认为是直的。编写此功能的最佳方法是什么?
这是Rank / Suit枚举类型代码,如果有帮助的话。
public enum Rank
{
TWO(2), THREE(3), FOUR(4), FIVE(5), SIX(6), SEVEN(7), EIGHT(8), NINE(9),
TEN(10), JACK(11), QUEEN(12), KING(13), ACE(14);
private final int points;
private Rank(int points)
{
this.points = points;
}
public int points()
{
return this.points;
}
}
public enum Suit
{
DIAMONDS, CLUBS, HEARTS, SPADES;
}
答案 0 :(得分:9)
你是否意识到,根据任何扑克游戏的规则,我曾经玩过或听说过一条直道不能包好吗? Ace可以低[A,2,3,4,5]或高[10,J,Q,K,A],但不能包裹。根据这些规则(不是你的规则),我之前已经实现了类似的规则。基本上你对数组进行排序并走它,确保当前的卡比前一个更高。在第一次迭代中,如果它是一个ace,那么你明确检查[A,2,3,4,5]。如果是,则返回true,如果不是,则继续使用正常的直线逻辑。这应该让你朝着正确的方向前进。
答案 1 :(得分:3)
你可以编写一个花哨的算法,尽管有可能的牌数,但是如果你发现在排序的牌上只有10个有效的组合,你可以找到这些:
2-6, 3-7, 4-8, 5-9, 6-T, 7-J, 8-Q, 9-K, T-A, (2-5,A)
答案 2 :(得分:3)
一般来说解决扑克牌的好方法是为每个牌分配一个比特值(比特(2)* 2)位设置以及比特(套装+ 28)设置,(所以2 = 1, 3 = 4,4 = 16等,直到A = 0x1000000)。然后将所有卡加在一起(调用结果'Sum'。计算V1 =(Sum& 0x2AAAAAA)>> 1,V0 =(Sum& 0x1555555),V2 = V1& V0。五张牌的值,并计算V3 = OrValue& 0xF0000000;
这种方法所需的测试应该可以用最少量的分支快速实现。
答案 3 :(得分:2)
由于您列表中只有5张牌,您可以对其进行排序并确定2张连续牌之间的差异。如果它包含一个ace,你需要将其视为低卡。如果所有差异都是1(或-1,具体取决于排序顺序),那么你就得到了直线。
答案 4 :(得分:0)
我认为,鉴于RANK的定义,直道只能从ACE.points() - 4的最大值开始。
所以,如果你按手分类,最低RANK是> ACE.points() - 4然后你就不能有一个笔直,否则你只需要在手上迭代,看看每张卡都是先前的RANK + 1.
如果ACE可以高或低,那么请使用SHS回答的内容。
答案 5 :(得分:0)
使用内部循环它是非常微不足道的,挑战将是没有内循环...
此外,这取决于您是否了解您的老师或您的老师误解(或歪曲)游戏规则。
我想我很想创建一个数组[2..14]并将卡片放在与其排名相对应的位置。如果你复制了一个副本,它就不是直的,当你完成后,你应该连续有8个空格。如果连续少于8个空格,则不是直线。
我能提出的所有其他解决方案都需要一个内部循环 - 内部循环是你需要避免的那些草率的编程事项之一,如果你将成为一个受人尊敬的程序员,你需要避免。
编辑:另外,如果你误解了老师并且唯一的包装条件是“10,j,q,k,a”(就像在实际规则中一样),那么你需要一个额外的测试,如果全部是2,13设置了14,它也是一个失败(2-ak环绕)。
(在重新阅读问题之后,再次编辑为替换1为ace与14)
答案 6 :(得分:0)
我不使用enum,我更喜欢命名常量,但我会假设从“ACE”到“14”是微不足道的
我懒得写真正的java代码(旁边你实际上要做你的作业^^)
check if the list has 5 cards
convert card names to a card number list named array
sort the list array
for i=1 to 4
if not (array[i] + 1) % 13 == (array[i+1]) % 13
then it is not a straight
%运算符被称为模数,因此(15%13)== 2 每当我面对“结束”挑战时,我都会使用此运算符
编辑:重新阅读您的问题后,我的解决方案无法开箱即用。您应该重新排序枚举,以便TWO == 0
答案 7 :(得分:0)
我建议使用位向量来表示卡片。这避免了必须排序。您可以添加两次ace(一次作为1,另一次作为一个王)或者您可以通过在检查是否设置2之前检查是否设置了ace位来特殊情况下的起始情况。如果速度很重要,你可以建立一个大的查找表。这种方法也可以清洁秤以找到其余的手(冲洗,2对,满屋,旅行等)。它还可以很容易地确定给定的直线是否高于另一直线。并且它完全扩展到7卡评估员
在伪代码中,对于非常一般的情况,它看起来像这样(你可以有任意数量的牌。它会直接返回)
long cardBitMask
for each card in hand
setBit in cardBitMask
hearts = mask(cardBitMask)
diamonds = mask(cardBitMask)
clubs = mask(cardBitMask)
spades = mask(cardBitMask)
// find straight
uniqueCards = hearts|diamonds|clubs|spades
int cardsInaRow = 0
if uniqueCards&AceCardMask:
cardsInaRow = 1
for card = 2...King
if uniqueCards&(1<<card)
cardsInARow++
else
if cardsInARow == 5
break
cardsInARow = 0
if cardsInARow==5:
return true
return false
答案 8 :(得分:0)
按顺序将所有等级添加到列表中,两次。然后,检查一只手是否为直线,按等级对手进行排序,然后检查该手是否是该列表的子列表。
答案 9 :(得分:-2)
您可以编写一个将每张卡转换为特定卡值的类
小丑= 11 女王= 12 国王= 13 Ace = 0或14 这将使卡片处理和寻找可能的手更容易。