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

您必须先从五张牌中取出三张同类牌。三样是真的暗示二样是真的。集合需要是不相交的。

于 2010-10-04T18:30:21.253 回答
1

您缺少第三个条件:三元组必须是与对子不同的牌。苏......因为你有这个共享的“卡片”数组,你可能可以将卡片“标记”为计数,并重置每次通过的计数状态:

//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 回答
1

因为其中三个也有一对(实际上在您的代码中可能是 2 对)

一种方法是按等级对手进行排序,然后它只是检测船的条件。

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 回答
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

当有三张卡片时,您的 isPair() 方法将始终返回 true,因为您的内部循环始终仅测试 y 值直到 x。

因此,使用此数据 AAA78,当 x = 1 y = 0 时,您将在内循环中获得 count == 1 并返回 true,尽管有三种类型。最好循环整个数组并计算值

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

此外 - 最好使用 isNOfAKind() 形式的一个函数,它获取卡片数量作为参数,因为这两种方法本质上是相同的。

于 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。只有在没有比一对更好的情况下,它才应该返回 true。

于 2010-10-04T18:39:38.327 回答
0

根据您的代码内联注释(exactly two matches单词),您可能正在尝试以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,那么 ThreeOfAKind 和 isPair 都返回真,因为你有三个 A(和一对 A)。

于 2010-10-04T18:28:15.030 回答
0

如果你只处理五张牌,计算对子的数量应该得出一对,两对两对,三对三(例如,如果一个人有 As、Ad 和 Ac , 对是 As-Ad、As-Ac 和 Ad-Ac),四对是满堂彩,六对是四对。这个逻辑不适用于七手牌,因为它会算三,例如 AAKKQQJ(应该只算作两对,而不是三对),而 AAAKKKQ 算六(应该算作满堂) ,而不是四种)。

于 2010-10-05T00:58:40.543 回答