質問

I am working on a poker game. So far I am stuck on comparing poker hands. I sort of have an idea on how to do it but I am not sure what is wrong with my code. Can somebody please point out what's wrong?

So let me give a brief description of what my code is doing.

My other part of the program will go through the cards in my hand and list the frequency of a card value in an array.

h = Hearts
c = Clubs
d = Diamonds
s = Spades
d4 = 4 of Diamond

So let's say in my hand I have c3, h4, d4, s4, 2d I will call the other part of my program to read the cards in my hand and return a tally array. The tally array for my hand above will be [0,0,1,1,3,0,0,0,0,0,0,0,0,0] So pretty much what this array is saying is that my hand has one 2, one 3 and three 4.

Now here is my method on trying to find Three of a Kind, it should return false for full house (which is three of a kind plus a pair)

public boolean hasThreeOfAKind() {
    int [] temp;
    temp = this.getCounts();
    for (int i = 0; i< temp.length; i++){
        if (temp [i] == 3 ){
            for (int j = 0; j < temp.length ; j++)
                if ( temp [j] != 2){
                    return true;
                }
        }
    }return false;

So what I am trying to do above is first, I run through the array, and if if there is any 3. If there is a 3, I run through the array again and see if there is a 2. and if there is not a 2, then I know it is three of a kind. If there is a 2, then it is full house and I should return false. I think my logic is correct, but there is something wrong with my code.

And the second hand that I am having trouble is how to determine if my hand has EXACTLY one pair. It only return true if there is only one pair. Return false if there are two pairs etc.

public boolean hasOnePair() {
    int [] temp;
    temp = this.getCounts();

    for (int i = 0; i< temp.length; i++){
        if (temp [i] == 2 ){
            return true;
        }
    }return false;

For this one, I am thinking of sort the value in the array either in descending or ascending order. If I chose the descending order, I first read the array and see if there is a 2, then I could scan the next one and see if the next value after the first 2 is also a 2. If there is another 2, then it would return false.

Can somebody please take a look at my code and point out what's wrong? Thank you very much.

役に立ちましたか?

解決

In your hasThreeOfAKind() you have the following error:

for (int j = 0; j < temp.length ; j++) 
  if ( temp [j] != 2){ 
    return true; 
  } 
} 

This will return true the first time it finds a non-2 j (which will be statisfied with the 3 you just checked above it -- thus returns true for a full house. You need instead:

boolean foundTwo = false;
for (int j = 0; j < temp.length ; j++) 
  if ( temp [j] == 2){ 
    foundTwo = true; 
  }
} 
if (!foundTwo) {
  return false;
}

Similarly for the other: you need to check if you find another 2 that is different from the one you already found:

for (int i = 0; i< temp.length; i++) {  
  if (temp [i] == 2 ){
    boolean foundAnother = false;
    for (int j = 0; j< temp.length; j++) { 
      if (i != j && temp [j] == 2 ){
        foundAnother = true;  
      }  
    }
    if (!foundAnother) {
      return true;
    }
  }  
}
return false;  

Another thing you could do is have filters for each recognized hand: a pair-filter, a three-filter, a full-house-filter, etc. and run all those filters through the hand. Don't worry if there is a better (higher value) match, just see which filters return true (found the pattern they were looking for) and select the highest point value among the ones that passed

他のヒント

Why are you working with such low level primitives? Is there a reason you're not using a full fledged Card class? Your code would be much simpler.

class Card
  enum Value {
    TWO,
    ...
    ACE
  };

  enum Suit {
    SPADES,
    ...
    CLUBS

  };
  private Suit suit;
  private Value value;

  public Card(Suit suit, Value value) {
    this.suit = suit;
    this.value = value;
  }
}

public class Hand {
  private final List<Card> cards;
  public Hand(Card first, Card second, Card third, Card fourth, Card fifth) {
     // add to cards list.

     // sort ascending by value

  }

  public boolean hasThreeOfAKind() {
    for (int i = 0; i < 3; i++) {
      Value firstValue = cards.get(i).getValue();
      Value secondValue = cards.get(i+1).getValue();
      Value thirdValue = cards.get(i+2).getValue();
      if (firstValue == secondValue && secondValue == thirdValue) {
        return true;
      }
    }
    return false;
  }
}

This doesn't directly answer your question, but in my opinion this sort of code is much more readable and maintainable and will be easier to debug than one involving only integers. Java isn't C and you don't really gain much by treating it like C.

In your threeOfAKind method, the second for loop will only get executed once unless the first number stored in your array is a 2, it should look more like this:

public boolean hasThreeOfAKind() {
    int [] temp;
    temp = this.getCounts();
    for (int i = 0; i< temp.length; i++){
        if (temp [i] == 3 ){
            for (int j = 0; j < temp.length ; j++)
                if ( temp [j] == 2){
                    return false;
                }
        }
    }
    return true;
}

in the above code, the first time it hits a pair it realizes that the hand is a full house instead of a three of a kind, and returns false.

and as for your other method hasOnePair() it should look more like:

public boolean hasOnePair() {
    int [] temp;
    temp = this.getCounts();
    int count = 0;

    for (int i = 0; i< temp.length; i++){
        if (temp [i] == 2  ){
            count++;
        }
    }
    return count == 1;
}

Look for the number of each similar card and make arrays. SO cards{1,1,2,2,2,5,7} (lets ignore the suits for now) will map to (3,2,1,1) i.e a full house you can check the second array easily

I'm helping my son with a similar problem for his Java Course at college (the course I used to teach) and this is what I would suggest.

First sort your cards from lowest to highest 2 to Ace regardless of suit. Then do comparing. If card[0]==card[3] or card[1]==card[4], you have 4 of a kind, ignore next 2 lines. If card[0]==card[2] or card[1]==card[3] or card[2]==card[4], you have 3 of a kind, ignore the next line. If card[0]==card[1] or card[1]==card[2] or card[2]==card[3] or card[3]==card[4], you have a pair.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top