so should I sort the values first and then check for sequences?
poker game
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.
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.
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.