5

フルハウス方式で困っています。スリーカードとペアをチェックするのと同じくらい簡単だと思いました。しかし、私の現在のコードでは、スリーカードだけでフルハウスを手に入れています。isFullHouse() isThreeOfAKind() および isPair() のコードは以下のとおりです。すべての助けに感謝します!

 public boolean isPair() {
     Pips[] values = new Pips[5];
     int count =0;

     //Put each cards numeric value into array
     for(int i = 0; i < cards.length; i++){
         values[i] = cards[i].getPip();
     }

     //Loop through the values. Compare each value to all values
     //If exactly two matches are made - return true
     for(int x = 1; x < values.length; x++){
         for(int y = 0; y < x; y++){
             if(values[x].equals(values[y])) count++;
         }
         if (count == 1) return true;
         count = 0;
     }
     return false;  
 }

 public boolean isThreeOfAKind() {
    Pips[] values = new Pips[5];
    int counter = 0;

    for(int i = 0; i < cards.length; i++){
        values[i] = cards[i].getPip();
    }

    //Same process as isPair(), except return true for 3 matches
    for(int x = 2; x < values.length; x++){
         for(int y = 0; y < x; y++){
             if(values[x].equals(values[y]))
                 counter++;
         }
         if(counter == 2) return true;
         counter = 0;
    }

    return false;
}

public boolean isFullHouse(){
    if(isThreeOfAKind() && isPair())
        return true;
    return false;
}
4

11 に答える 11

9

ペアがスリーカードとは異なるランクであることを確認してください。それ以外の場合、isPair()関数はスリーカードと同じカードを見つけます。多分このように:

public boolean isFullHouse(){
    int three = isThreeOfAKind();
    int pair = isPair();
    if (three != 0 && pair != 0 && three != pair) {
        return true;
    }
    return false;
}

(私は を使用intしましたが、必要に応じて自分のタイプを使用するように変更できますPips。)

于 2010-10-04T18:26:20.073 に答える
6

ロジックを劇的に単純化する方法を提案できますか?

という名前のヘルパー メソッドを考えてみましょうpartitionByRank()

public class RankSet {
    private int count;
    private Rank rank;
}

/**
 * Groups the hand into counts of cards with same rank, sorting first by
 * set size and then rank as secondary criteria
 */
public List<RankSet> partitionByRank() {
   //input e.g.: {Kh, Qs, 4s, Kd, Qs}
   //output e.g.: {[2, K], [2, Q], [1, 4]}
}

手のタイプを取得するのは非常に簡単です。

public boolean isFullHouse() {
    List<RankSet> sets = partitionByRank();
    return sets.length() == 2 && sets.get(0).count == 3 && sets.get(1).count() == 2;
}

public boolean isTrips() {
    //...
    return sets.length() == 3 && sets.get(0).count = 3;
}

これは、あるペアが別のペアよりも大きいかどうかを必然的に確認する必要がある場合にも役立ちます。

于 2010-10-04T18:38:28.710 に答える
2

最初に 5 枚の手札から 3 種類のカードを取り除く必要があります。スリーカードが真であるということは、ツーカードが真であることを意味します。セットはバラバラである必要があります。

于 2010-10-04T18:30:21.253 に答える
1

スリーカードにもペアがあるためです (実際には、コードではおそらく 2 つのペアになります)。

これを行う 1 つの方法は、ハンドをランク​​で並べ替えてから、ボートを検出するための条件のみを指定することです。

if ( ((c1.rank == c2.rank == c3.rank) && (c4.rank == c5.rank)) ||
     (c1.rank == c2.rank) && (c3.rank == c4.rank == c5.rank))

余分なものがあるかもしれません(そこにあるかもしれませんが、あなたはアイデアを得る...

于 2010-10-04T18:26:56.593 に答える
1

You are missing a third condition: the triple needs to be different cards than the pair. Soo... since you have this shared "cards" array, you probably could "mark" the cards as counted, and reset the counted status for each pass:

//Same process as isPair(), except return true for 3 matches
for(int x = 2; x < values.length; x++){
     cards[x].setCounted(true);  // by default, count the start card
     for(int y = 0; y < x; y++){
         // make sure the card isn't already counted:
         if(!cards[y].isCounted() && values[x].equals(values[y])) {
             counter++;
             cards[x].setCounted(true); // count it
         }
     }
     if(counter == 2) return true;
     counter = 0;
     // reset counted cards
     for(int z=0, zlen=values.length; z < zlen; z++) { cards[z].setCounted(false); }
}
于 2010-10-04T18:42:38.647 に答える
0

問題に対するより良い一般的なアプローチ - これは C# ですが、Java への変換は簡単です。

int[] countOfRank = new int[13];
int[] countOfSuit = new int[4];
for(int i = 0; i < cards.length; i++)
{
     countOfRank[cards[i].Rank]++;
     countOfSuit[cards[i].Suit]++;
}

for (int i=0; i < countOfSuit.length; i++)
{
   isFlush = isFlush || countOfSuit[i] == 5;
}

int[] countOfTuple = new int[5];
int runLength=0;
for (int i=0; i < countOfRank.length; i++)
{
   if (countOfRank[i] == 1)
   {
      runLength++;
      isStraight = (isStraight || runLength == 5);
   }
   else
   {
      runLength=0;
   }
   countOfTuple[countOfRank[i]]++;
}
isPair = (countOfTuple[2] == 1 && countOfTuple[3] == 0);
isTwoPair = (countOfTuple[2] == 2);
isFullHouse = (countOfTuple[2] == 1 && countOfTuple[3] == 1);
isThreeOfAKind = (countOfTuple[2] == 0 && countOfTuple[3] == 1);
isFourOfAKind = (countOfTuple[4] == 1);
isStraightFlush = (isStraight && isFlush);
isStraight = (isStraight && !isStraightFlush);
isFlush = (isFlush && !isStraightFlush);
isRoyalFlush = (isStraightFlush && countOfRank[12] == 1);
isStraightFlush = (isStraightFlush && !isRoyalFlush);
于 2010-10-04T18:58:32.960 に答える
0

5 枚のカード ハンドのみを扱っている場合、ペアの数を数えると、ペアの場合は 1、ツー ペアの場合は 2、スリー オブ ア カインドの場合は 3 になります (たとえば、1 人が As、Ad、Ac を持っている場合)。 、ペアは As-Ad、As-Ac、および Ad-Ac です)、フルハウスの場合は 4 つ、フォーカードの場合は 6 つです。このロジックは 7 枚のカード ハンドでは機能しません。たとえば、AAKKQQJ (スリーオブ ア カインドではなく、2 ペアとしてのみカウントする必要があります) の場合は 3 とカウントされ、AAAKKKQ (フル ハウスとしてカウントする必要があります) の場合は 6 とカウントされるためです。 、フォーカードではありません)。

于 2010-10-05T00:58:40.543 に答える
0

コードのインライン コメント ( exactly two matcheswords)によると、3 種類の組み合わせの場合にisPair返されるような方法でメソッドを実装しようとしている可能性があります。falseその場合は、次のように isPair メソッドを変更して、配列内のすべての項目を反復処理する必要があります。

//Loop through the values. Compare each value to all values
     //If exactly two matches are made - return true
     for(int x = 0; x < values.length; x++){
         for(int y = 0; y < values.length; y++){
             if(y != x && values[x].equals(values[y])) count++;
         }
         if (count == 1) return true;
         count = 0;
     }
于 2011-08-17T17:08:45.033 に答える
0

ペアがスリーカードとは異なるツーカードであることを確認する必要があります。ハンドが AAA 7 8 の場合、3 つのエース (およびエースのペア) があるため、ThreeOfAKind と isPair の両方が true を返します。

于 2010-10-04T18:28:15.030 に答える
0

同じ種類のカードが 3 枚ある場合、 isPair() メソッドは常に true を返します。これは、内部ループが常に x までの y 値のみをテストするためです。

したがって、このデータ AAA78 では、x = 1 y = 0 の場合、内側のループで count == 1 を取得し、true を返しますが、3 つの種類があります。次の場合は、配列全体をループして値をカウントすることをお勧めします。

if(values[x].equals(values[y]) && x != y)

さらに、isNOfAKind() の形式で 1 ​​つの関数を使用することをお勧めします。この関数はカードの枚数をパラメータとして取得します。これら 2 つのメソッドは本質的に同じことを行うからです。

于 2010-10-04T18:33:00.307 に答える
0

単なるアイデアですが、次のようなことを行う方が簡単ではないでしょうか:

int[] count=new int[13];//size of all ranks
for (i=0;i<5;i++)
  count[ card[i].rank ] ++;

たとえば0 0 0 0 0 3 0 0 0 2 0 0 0 0、フルハウスの場合です。ストレートは 5 つが連続しているように見えます: 0 0 0 0 1 1 1 1 1 0 0 0.

メソッドはパブリックなのでisPair()、ペアが存在する場合にメソッドが true を返すことは望ましくありません。1 つのペアより優れたものがない場合にのみ true を返す必要があります。

于 2010-10-04T18:39:38.327 に答える