Advertisement

poker game

Started by November 01, 2024 12:29 AM
173 comments, last by Alberth 7 hours, 16 minutes ago

so should I sort the values first and then check for sequences?

I'm not saying "what" to do.
Only giving some thoughts to think about.
What have you tried?

Maybe slow down for a moment.
You've been pushing pretty hard in a good direction.
Take some time to do a clean-up pass over your code. Then do it again.
Make sure you are organized and have a solid understanding of all you've done up to this point.
Go back over this entire thread to review your progress.
You're now at a point where everything comes together or fails miserably.

But to answer your question, I sorted first in my finished solution and then did the sequence check.
It get's pretty advanced and I'm trying not to overwhelm you.
If you get stuck and thinking of giving up, I'll let you have mine.

Dev careful. Pixel on board.

Advertisement

thx for all the input

I have put an algorithm in my code for flush's and it works I am working on straights

taby said:

I still think that it’s best to make a set of sieves, starting with Royal Flush down to High Card. 🙂

There's an opportunity to early out of the evaluation when the simpler checks hit, signaling straight or flush as not possible.

Dev careful. Pixel on board.

I figured out how to do straights all I need to do is the straightflush and the royal flush.

Advertisement

For me, it was just a couple of if statements using my previously gathered information.
Here is my evaluation routine in it's entirety for reference if you so wish.

Listing some references of language features used:
https://en.cppreference.com/w/cpp/utility/functional/modulus
https://en.cppreference.com/w/cpp/utility/bitset
https://en.cppreference.com/w/cpp/algorithm/sort with lambda argument
https://en.cppreference.com/w/cpp/algorithm/rotate
That's pretty much all I used. The rest was logic.

Thank you for the interaction. That was enjoyable.


struct HandInfo
{
    int cards[5];                 // actual card ID from the deck
    int highest_card_index;       // used on zero ranking
    int rank;                     // used for determining hand strength 
};


void RankHand(HandInfo* hand)
{
   //   solveable by comparison   |   determine by additional steps                    
   // ============================|=================================
   // nothing        =  0  (0)    |         (highest card)
   // one pair       =  2  (4)    |
   // two pair       =  4  (8)    |
   // three of kind  =  6  (12)   |
   //                      (14)   |         (straight)
   //                      (15)   |         (flush)                        
   // full house     =  8  (16)   |
   // four of a kind = 12  (24)   |
   //                      (25)   |         (straight flush)
   //                      (26)   |         (royal straight flush)
   hand->highest_card_index = 0;
   hand->rank = 0;
   bool flush_found    = false;
   bool straight_found = false;
   bool make_ace_high  = false;
   
   // find high card ---------------------------------------------------------------------------
   for (int i = 0; i < 5; i++)
   {
       int a = hand->highest_card_index % 13;
       int b = hand->cards[i] % 13;
       if (a == 0) a = 13;
       if (b == 0) b = 13;
       if (b > a)  hand->highest_card_index = hand->cards[i];
       else if (b == a)
       {   // choose the higher suit of this card value
           if (hand->cards[i] > hand->highest_card_index)
               hand->highest_card_index = hand->cards[i];
       }
   }
   
   // process rank solvable by comparison ------------------------------------------------------
   for (int i = 0; i < 5; i++) 
   {
       for (int j = 0; j < 5; j++)
           if (i != j && ((hand->cards[j] % 13) == (hand->cards[i] % 13)))
               hand->rank++;
   }   
   hand->rank *= 2;                   // double result to make room for additional ranks
   if (hand->rank > 0) return;        // early out (can not be straight or flush)
   
   // continue evaluation checking for flush hand ----------------------------------------------
   std::bitset<4> suit_bitset;
   for (int i = 0; i < 5; i++)
   {
       if (hand->cards[i] < 14) suit_bitset.set(0);                            // clubs
       if (hand->cards[i] > 13 && hand->cards[i] < 27) suit_bitset.set(1);     // diamonds
       if (hand->cards[i] > 26 && hand->cards[i] < 40) suit_bitset.set(2);     // spades
       if (hand->cards[i] > 39) suit_bitset.set(3);                            // hearts
   }
   if (suit_bitset.count() == 1) flush_found = true;
   
   // check for straight -----------------------------------------------------------------------
   std::sort(hand->cards, hand->cards + 5, 
       [](const int& first, const int& second) -> bool
       {   // keeping connection to deck representation (handle Ace later)
           int a = first % 13;
           int b = second % 13;
           return a < b;
       }
   );
   straight_found = true; // default true for sequential test
   if ((hand->cards[4] % 13 == 12) && (hand->cards[0] % 13 == 0))
   {   // King is present. rotate Ace to the back.
       make_ace_high = true;
       std::rotate(&hand->cards[0], &hand->cards[0]+1, &hand->cards[5]);
   }
   for (int i = 0; i < 4; i++)
   {
       int a = hand->cards[i] % 13;
       int b = hand->cards[i + 1] % 13;
       if (make_ace_high)
       {
           if (a == 0) a = 13;
           if (b == 0) b = 13;
       }
       if( b - a != 1 )
       {
           straight_found = false;
       }
   }
   
   // final rank determination from gathered information ---------------------------------------
   if (straight_found && flush_found && (hand->cards[4] % 13 == 0)) hand->rank = 26; // is royal straight flush?
   else if (straight_found && flush_found) hand->rank = 25;                          // is straight flush?
   else if (flush_found) hand->rank = 15;                                            // is flush?
   else if (straight_found) hand->rank = 14;                                         // is straight?
}

// todo: when checking win on a tie, suit matters.
//       just compare high card on straight and flush
//       or compare high card % 13 for others 
//       remember to consider the Ace special case

Dev careful. Pixel on board.

Are you planning on doing a computer player?

If so, then you’ll have to come up with a function that takes a hand and the deck not dealt yet, and then gives the best possible hand by using wildcard spots. And yes, before you try to classify a best possible hand, you will want to sort the hand. 🙂

well nub I will use your code as reference and yes I will do a computer player eventually.

Ok. You can use a simple cpu player, like always making random decisions for instance. A placeholder player AI, basically. This way you can focus on the architecture before you focus more on the decision making code at a later date. Just a thought.

Advertisement