对于一个家庭作业给了我一张卡片类已经列举的类型和等级的诉讼。我需要比较两个扑克牌(每个手是一个 ArrayList 5张牌)并决定赢家。

isStraight() 功能是真的烦我,因为我要开始最后的王牌。例如,

王后,国王,王牌,二,三

仍然被认为是一条直线。什么是最好的方式来代码这种功能?

这里是秩/适合所列举的类型代码,如果有帮助。

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;
}
有帮助吗?

解决方案

您知不知道任何扑克游戏的规则,我打过或听到直不能完成正确的? ACE可以是低[A,2,3,4,5]或高[10,J,Q,K,A],但它不能完成。根据这些规则(不是你)我实现了类似之前的东西。基本上你排序的阵列和走它,确保当前的卡比以前更高的一个。在第一次迭代中,如果是高手,那么你明确检查[A,2,3,4,5]。如果你返回true,如果它是不是你继续正常直逻辑。这应该设置你在正确的方向。

其他提示

一个很好的办法对于解决扑克牌一般是分配给每个卡的一位值与位((秩-2)*2)位设置以及位(适+28)设定,(所2=1, 3=4, 4=16, 等等。一=0x1000000).然后添加在一起所有的卡(电话,结果总和'.计算V1=(Sum&0x2AAAAAA)>>1,0=(Sum&0x1555555),并V2=V1&0.也或者在一起的价值观的五张卡片和计算V3=OrValue&0xF0000000;

  1. 一对,V1将有一个单位集合,0将有多个位置,并V2将为零。
  2. 两对,V1将有两个位置和V2将等于零。
  3. 为三类,V1将有一个单位集合,和V2会平等V1。
  4. 一直,0将0x1000055或其他力量的两倍0x155.
  5. 对一个冲洗,V2将有一个精确位置。
  6. 对于一个完整的家,V1将有两位置,并V2将非零。
  7. 对四种,无论是V1将两次0,两者具有一个位置,或者0将有精确的两个位置和V1将为零。
  8. 一个同花顺,条件下直接和冲将得到满足。

这个测试需要这种方法应该是可实施迅速有最少量的分支。

您可以编写一个花哨的算法,尽管可能卡的数量返回true,但如果你知道一个排序的手上只有10个有效组合,你可以只看看这些:

2-6, 3-7, 4-8, 5-9, 6-T, 7-J, 8-Q, 9-K, T-A, (2-5,A)

由于只有5您列表卡,你可以对它进行排序并确定2个连续卡之间的区别。如果它包含一个王牌,你需要考虑它作为一种低卡了。如果所有的差异是1(或-1,根据不同的排序顺序),你有你的直线。

我认为,给出的RANK该定义,其直道只能与ACE.points()的最大启动 - 4

所以,如果你解决你的手,最低等级为> ACE.points() - 4,那么你不能有直的,否则你只是迭代的手,看到每个卡是以前的RANK + 1

如果ACE可高可低,那么什么SHS回答去了。

通过一个内部循环是很琐碎,面临的挑战将是做没有一个内部循环......

此外,它取决于如果你了解你的老师或你的老师误解(或歪曲)的游戏规则。

我想我被诱惑只是创建一个数组[2..14],并把卡在对应于它们的等级位置。如果你打副本,它不是一条直线,而当你完成,你应该有一排8个空格。如果你有一排不到8个空格,它不是一条直线。

所有其他解决方案,我可以拿出需要一个内环 - 和内环是你需要避免时,你可以,如果你打算永远是一个值得尊敬的程序员那些草率的编程事情之一

编辑:另外,如果你误解教师和仅包裹条件“10,J,Q,K,A”(如在现实的规则),则需要额外的测试所有的2,如果,13和14被设置,它也是一个失败(2-AK环绕)。

(再次编辑重新阅读的问题后,用14来代替1 ACE)

我不使用枚举了,我更喜欢命名的常量但我会认为从“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 每当我面对“包裹在”挑战我使用此操作符

编辑:在重新阅读你的问题后,我的解决方案不能工作开箱。你应该重新排序枚举这样两个== 0

我建议使用一个位向量以表示卡。这样就避免了排序。您可以(为1,一旦其他时间作为一个国王)添加王牌两次或者您也可以特殊情况下,如果由王牌位,如果2设置检查)之前设置检查启动情况。你可以建立,如果速度事项一大查找表。这种做法也清洗秤找到手(刷新,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

为了将所有的队伍名单,两次。然后,检查是否有手的直链,由等级排序的手,然后检查如果手是该列表的子列表。

你可以写,每卡转换为特定的卡值一类

=小丑11 大号= 12 王= 13 ACE = 0或14

它将使轻松了许多卡处理,并寻找可能的手中。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top