0

我正在尝试编写一个非常简单的扑克游戏。我只是使用非面卡,2-9,没有套件或类似的东西。我试图弄清楚如何编写一个方法来确定五张牌是否是满屋,这是一对和一个 3。我让用户输入 5 个表示卡片值的整数并将它们存储在一个数组中。我试着写这样的东西:

public static boolean containsFullHouse(int[] hand)
{
     for (int i = 0; i < hand.length; i++){
         int count = 0;

         for (int j = 0; j < hand.length; j++){
              if (hand[i] == hand[j]){
                 count++;}

              if (count == 3){
                 return true;}
         }
     }
         for(int i = 0; i < hand.length; i++){
              for(int j = i + 1; j < hand.length; j++){ 
                  if(hand[i] == hand[j]){
                        return true;}
                   }
               }
         }  
    return false;
}
4

4 回答 4

2

您需要计算每个数字的出现次数,并创建所谓的基数图。那么基数必须是 (2,3) 或 (3,2)。如果不使用 guava 或 Apache Commons Collections(其中包含执行此操作的便捷方法),可以通过以下方式完成:

public static boolean isFullHouse(final int[] input) {
    if (input.length != 5) { throw new IllegalArgumentException("need 5 integers"); }
    Map<Integer, Integer> cardinalityMap = new HashMap<>();
    for (int i : input) {
        if (cardinalityMap.containsKey(i)) {
            cardinalityMap.put(i, cardinalityMap.get(i) + 1);
        }
        else {
            cardinalityMap.put(i, 1);
        }
    }

    if (cardinalityMap.size() != 2) { return false; }
    Collection<Integer> occurences = cardinalityMap.values();
    int first = occurences.iterator().next();
    return first == 2 || first == 3;
}
于 2013-09-18T10:10:08.773 回答
1

问题:

  • 您正在检查 indexi两次,虽然是正确的(因为您检查了count == 3),但这是不必要的。
  • 在检查其他 2 个之前,您也会返回。
  • 第二个循环将返回 true,因为它会从前一个循环中找到数字。

如果对它们进行排序,则可以简单地检查两侧的两对卡片是否相同,并检查中间卡片是否与其中任何一张相同。所以是这样的:

Arrays.sort(hand);
return (hand[0] == hand[1] && hand[3] == hand[4] &&
        (hand[2] == hand[1] || hand[2] == hand[3]));

或者,如果您想修复您的功能:

public static boolean containsFullHouse(int[] hand)
{
     // a variable that keeps track of one of the 3-of-a-kind indices (used in 2-of-a-kind check)
     int pos = -1;

     for (int i = 0; i < hand.length && pos == -1; i++){
         // start count at one instead
         int count = 1;

         // start j from next position rather than 0
         for (int j = i+1; j < hand.length && pos == -1; j++){
              if (hand[i] == hand[j]) {
                 count++;
              }

              if (count == 3) {
                 pos = i;
              }
         }
     }

     // if we didn't find 3-of-a-kind, return false
     if (pos == -1)
         return false;

     // look for 2-of-a-kind
     for(int i = 0; i < hand.length; i++){
         // exclude elements that match one of the 3-of-a-kind
         if (hand[i] != hand[pos]){
             for(int j = i + 1; j < hand.length; j++){ 
                 if(hand[i] == hand[j]){
                        return true;
                 }
             }
         }
     }

    return false;
}
于 2013-09-18T09:53:37.717 回答
1

我会使用 Apache Commons 的 CollectionUtils.getCardinalityMap 来做到这一点

public static void main(String[] args) {

    Integer[] fullHouse = new Integer[]{7, 7, 7, 4, 4};
    Integer[] notFullHouse = new Integer[]{2, 2, 2, 2, 3};
    Integer[] notFullHouse2 = new Integer[]{1, 4, 2, 2, 3};

    System.out.println(isFullHouse(fullHouse));
    System.out.println(isFullHouse(notFullHouse));
    System.out.println(isFullHouse(notFullHouse2));

}

private static boolean isFullHouse(Integer[] cards){
    Map<Integer,Integer> cardinalityMap = CollectionUtils.getCardinalityMap(Arrays.asList(cards));

    if(cardinalityMap.size() == 2) {
        if (cardinalityMap.values().containsAll(Arrays.asList(2, 3))) {
            return true;
        }
        return false;
    }
    return false;
}
于 2013-09-18T10:11:05.573 回答
0

满屋由 2 个不同的整数组成,因此请为两者保留一个计数器。它还需要跟踪 2 个不同的值。如果你把它结合起来,你会得到这样的东西:

public static boolean containsFullHouse(int[] hand)
{
    int value1 = -1, count1 = 0;
    int value2 = -1, count2 = 0;

    for (int i = 0; i < hand.length; i++) {
        if(hand[i] == value1) {
            // Found another value1 card
            count1++;
        } else if(hand[i] == value2) {
            // Found another value2 card
            count2++;
        } else if(value1 == -1) {
            // Found a new card, store as value1
            value1 = hand[i];
            count1++;
        } else if(value2 == -1) {
            // Found a new card, store as value2
            value2 = hand[i];
            count2++;
        } else {
            // Found a third card, so it cannot be a full house!
            return false;
        }
    }
    if(value2 == -1) {
        // Found 'five of a kind'?!
        return false;
    }

     // Check if it is a full house
    return (count1 == 3 && count2 == 2) || (count1 == 2 && count2 == 3;)
}
于 2013-09-18T09:54:50.777 回答