7

宿題で、ランクとスーツの種類が列挙された Card クラスが与えられました。2 つのポーカー ハンド (各ハンドはArrayList5 枚のカード) を比較し、勝者を決定する必要があります。

エースの後にカウントをやり直さなければならないので、この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;
}
4

10 に答える 10

10

私が今までプレイした、またはストレートについて聞いたポーカーゲームのルールでは、正しくラップできないことをご存知ですか?エースは低い[A、2,3,4,5]または高い[10、J、Q、K、A]にすることができますが、ラップすることはできません。それらのルール(あなたのルールではない)によると、私は以前に同様の何かを実装しました。基本的に、配列を並べ替えてウォークし、現在のカードが前のカードより1つ高いことを確認します。最初の反復で、それがエースである場合は、[A、2,3,4,5]を明示的にチェックします。そうである場合はtrueを返し、そうでない場合は通常のストレートロジックを続行します。これにより、正しい方向に進むはずです。

于 2009-02-09T22:10:45.180 に答える
4

考えられるカードの数に関係なく true を返す高度なアルゴリズムを作成できますが、並べ替えられたハンドに有効な組み合わせが 10 しかないことに気付いた場合は、これらを探すことができます。

2-6, 3-7, 4-8, 5-9, 6-T, 7-J, 8-Q, 9-K, T-A, (2-5,A)
于 2009-02-20T16:12:59.687 に答える
3

一般的にポーカー ハンドを解決するための優れたアプローチは、各カードにビット ((rank-2)*2) ビット セットとビット (スーツ + 28) セットのビット値を割り当てることです (つまり、2=1、3=4)。 、4=16 など、A=0x1000000 まで)。次に、すべてのカードを合計します (その結果を「Sum」と呼びます。V1=(Sum & 0x2AAAAAA)>>1、V0=(Sum & 0x1555555)、および V2=V1 & V0 を計算します。また、5 枚のカードの値を OR します。 、および V3=OrValue & 0xF0000000 を計算します。

  1. ペアの場合、V1 には 1 つのビットが設定され、V0 には複数のビットが設定され、V2 にはゼロが設定されます。
  2. 2 ペアの場合、V1 には 2 つのビットが設定され、V2 はゼロに等しくなります。
  3. スリー オブ ア カインドの場合、V1 には 1 つのビット セットがあり、V2 は V1 に等しくなります。
  4. ストレートの場合、V0 は 0x1000055 か、0x155 の 2 の累乗倍数になります。
  5. フラッシュの場合、V2 には正確に 1 つのビット セットがあります。
  6. フルハウスの場合、V1 には 2 つのビットが設定され、V2 は非ゼロになります。
  7. フォー・オブ・ア・カインドの場合、V1 が v0 の 2 倍で両方に 1 ビットが設定されるか、V0 に正確に 2 ビットが設定されて V1 がゼロになります。
  8. ストレート フラッシュの場合は、ストレートとフラッシュの条件が満たされます。

このアプローチに必要なこのテストは、最小限の分岐で迅速に実装できるはずです。

于 2011-12-19T04:26:15.183 に答える
0

そのRANKの定義を考えると、ストレートはACE.points()-4の最大値でのみ開始できると私は主張します。

したがって、手を並べ替えて、最低のRANKが> ACE.points()-4の場合、ストレートを作成することはできません。それ以外の場合は、手を繰り返して、各カードが前のRANK+1であることを確認します。

ACEが高くても低くてもよい場合は、SHSが回答した内容を使用してください。

于 2009-02-09T22:44:05.897 に答える
0

内部ループを使用すると、それはかなり簡単です。課題は、内部ループなしで実行することです...

また、あなたが先生を理解したか、それとも先生がゲームのルールを誤解した (または誤って伝えた) かによっても異なります。

配列 [2..14] を作成して、ランクに対応する場所にカードを配置したくなると思います。重複をヒットした場合、それはストレートではなく、終了すると、8 つのスペースが連続して表示されます。連続するスペースが 8 つ未満の場合、それはストレートではありません。

私が思い付くことができる他のすべての解決策には、内部ループが必要です。内部ループは、立派なプログラマーになるためには、できる限り避ける必要があるずさんなプログラミングの 1 つです。

編集: また、教師を誤解し、ラッピング条件が "10,j,q,k,a" (実際のルールのように) だけの場合は、2、13、14 のすべてがこれも失敗です (2-ak ラップアラウンド)。

(質問を読み直した後、エースの1を14に置き換えるために再度編集しました)

于 2009-02-09T23:00:50.707 に答える
0

すべてのランクを順番にリストに 2 回追加します。次に、ハンドがストレートかどうかを確認するには、ハンドをランク​​で並べ替えてから、そのハンドがそのリストのサブリストであるかどうかを確認します。

于 2009-02-10T20:13:47.457 に答える
0

カードを表すにはビット ベクトルを使用することをお勧めします。これにより、ソートする必要がなくなります。エースを 2 回 (1 回は 1 として、もう 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
于 2009-02-10T00:31:58.007 に答える
-2

すべてのカードを特定のカード値に変換するクラスを作成できます

ジョーカー = 11 クイーン = 12 キング = 13 エース = 0 または 14

カードの取り扱いと可能性のある手を探すのがずっと簡単になります。

于 2009-02-09T22:36:50.953 に答える