3

I'm working on getting my Poker to evaluate the player hand. I can get the Flush and the jack or better pair to work but am running into problems figuring out how I would do the rest. Any suggestions on how I can evaluate the cards to the appropriate type?

int Game::HandCheck()
{
    //ROYAL FLUSH
    //return 9;

    //STRAIGHT FLUSH
    //return 8;

    //FOUR OF A KIND
    //return 7;

    //FULL HOUSE
    //return 6;

    //FLUSH
    if( currentHand[ 0 ].GetSuit() == currentHand[ 1 ].GetSuit() && currentHand[ 1 ].GetSuit() == currentHand[ 2 ].GetSuit() &&
        currentHand[ 2 ].GetSuit() == currentHand[ 3 ].GetSuit() && currentHand[ 4 ].GetSuit() == currentHand[ 4 ].GetSuit() ) 
        return 5;

    //STRAIGHT
    //return 4;

    //THREE OF A KIND
    if( currentHand[ 0 ].GetValue() == currentHand[ 2 ].GetValue() && currentHand[ 0 ].GetValue() == currentHand[ 3 ].GetValue()
    //return 3;

    //TWO PAIR
    //return 2;

    //JACKS OR BETTER PAIR
    for( int i = 0; i < 5; i++ )
    {
        if( currentHand[ i ].GetValue() == 11 || currentHand[ i ].GetValue() == 12 || currentHand[ i ].GetValue() == 13 || currentHand[ i ].GetValue() == 1 )
        {
            if( currentHand[ i ].GetValue() == currentHand[ i + 1 ].GetValue() || currentHand[ i ].GetValue() == currentHand[ i + 2 ].GetValue() || //pair
            currentHand[ i ].GetValue() == currentHand[ i + 3 ].GetValue() || currentHand[ i ].GetValue() == currentHand[ i + 4 ].GetValue() )
            return 1;
        }
    }

    return 0;

}
Josh Lake
  • 567
  • 1
  • 6
  • 17
  • You need to improve your sense of idiomatic C++, this is what's letting you down. For example, the code to detect a flush is really bad; can you imagine if a hand was N cards instead of 5? It shouldn't be that hard. – Jon Dec 07 '11 at 22:43
  • Im not using dynamic memory so its working... – Josh Lake Dec 07 '11 at 22:47
  • I suggest you *sort* the hand before you evaluate it. Should make things a bit easier. – jrok Dec 07 '11 at 22:48
  • You can eliminate some checks, also. F.e. if you found a pair, you don't need to check for flush and straight, right? – jrok Dec 07 '11 at 22:50
  • If you convert hands to strings like '5h3hJcJd2s' or '53JJ2','hhcds' you can do regex against some of them. Sort for sequences, etc. There is no universal solution. – Mouse Food Dec 07 '11 at 22:51
  • You have to do the highest hand first otherwise you can have a pair = true but the hand really could be a full house. – Josh Lake Dec 07 '11 at 22:55
  • How many times do you get a pair and how many times do you get a royal flush? :) You don't need to return immediately from the function if you find a pair. You're doing lots of unnecessary checks like you have it at the moment. – jrok Dec 07 '11 at 22:58

2 Answers2

5

I would create a histogram array to do the counting.

Fill the array. If exactly one bucket has of count of two or more, you have a pair, trips or four of a kind. If two buckets have a count of two or more, you have two pair or a full house.

Steve Wellens
  • 20,506
  • 2
  • 28
  • 69
3

Your Flush algorithm is comparing 4 against itself:

//FLUSH
if( currentHand[ 0 ].GetSuit() == currentHand[ 1 ].GetSuit() && currentHand[ 1 ].GetSuit() == currentHand[ 2 ].GetSuit() &&
    currentHand[ 2 ].GetSuit() == currentHand[ 3 ].GetSuit() && currentHand[ 4 ].GetSuit() == currentHand[ 4 ].GetSuit() ) 
    return 5;
                                                                            ^^^---------------------------^^^

Your three-of-a-kind algorithm is assuming that all three values are in the first three positions:

//THREE OF A KIND
if( currentHand[ 0 ].GetValue() == currentHand[ 2 ].GetValue() && currentHand[ 0 ].GetValue() == currentHand[ 3 ].GetValue()
//return 3;

Perhaps the three identical values are stored in the first, middle, and last cards in the hand.

I don't know how traditional poker hand evaluators are written, but I have a feeling that they perform some extra computations: create an array, indexed by card value, that stores the count of the number of cards of that value:

int reverse_hand[13] = {0};

for (int i=0; i<HAND_SIZE; i++) {
    reverse_hand[currentHand[i].getValue()] += 1;
}

int pairs[2] = {-1, -1};
int pairs_count = 0;
int triple = -1;
int quad = -1;

int straight_pos = -1;

for (int i=0; i<13; i++) {
    count = reverse_hand[i];
    if (count == 2) {
        pairs[pairs_count++] = i;
    } else if (count == 3) {
        triple = i;
    } else if (count == 4) {
        quad = i;
    } else if (count == 1) {
        if ((i < (13-5)) && (reverse_hand[i] == 1) &&
                            (reverse_hand[i+1] == 1) &&
                            (reverse_hand[i+2] == 1) &&
                            (reverse_hand[i+3] == 1) &&
                            (reverse_hand[i+4] == 1)) {
            straight_pos = i;
    }
}

if (pairs_count == 2) {
    printf("You had two pairs, %d low and %d high\n", pairs[0], pairs[1]);
} else if (pairs_count == 1) {
    printf("YOu had one pair of %d\n", pairs[0]);
}

if (triple >= 0) {
    printf("You had a three of a kind: %d\n", triple);
}

if (quad >= 0) {
    printf("You had a four of a kind: %d\n", quad);
}

if (pairs_count == 1 && triple >=0) {
   printf("Full house, three %d and two %d\n", triple, pairs[0]);
}

/* code here for flush detection */

if (straight_pos >= 0) {
   int p = straight_pos;
   /* if straight flush print a different message */
   printf("Straight, %d %d %d %d %d\n", p, p+1, p+2, p+3, p+4);
}
sarnold
  • 102,305
  • 22
  • 181
  • 238
  • I fixed the flush but haven't finished the Three of a Kind yet. Could you maybe give an example of a straight giving the objects I have above? – Josh Lake Dec 07 '11 at 23:27
  • Fixing three-of-a-kind in the style of code you have now would be pretty ugly: you'd have to check 1, 2, 3; 1, 2, 4; 1, 2, 5; 2, 3, 4; 2, 3, 5; ... Better re-write the whole thing to get pairs, three-of-a-kind and four-of-a-kind in one go, right? – sarnold Dec 07 '11 at 23:32
  • Mid-way thru writing the three of a kind I figured it was gonna be crazy long. How would I reevaluate the cards from an array, such as the one you listed? – Josh Lake Dec 07 '11 at 23:36
  • I wouldn't rely exclusively on the array I suggested here (and is the same suggestion as [Steve's Histogram](http://stackoverflow.com/a/8423725/377270)) -- it would be very useful for finding pairs, two pairs, three of a kind, full house (one entry with `3`, one entry with `2`), four of a kind, straight (five consecutive entries with a `1`), and straight flush (same five consecutive entries with a `1`, combined with your existing array of cards to find suits). A flush would require your original data structure _or_ a new array like this to count the _suits_ as well. – sarnold Dec 07 '11 at 23:42
  • can I maybe get an example in actual code form what your trying to say? English isnt first language – Josh Lake Dec 08 '11 at 06:27
  • @Josh: I sketched out a little further how you'd use the histogram. – sarnold Dec 08 '11 at 08:13