diff --git a/src/dawn/poker/Card.cpp b/src/dawn/poker/Card.cpp index 6622523e..05e7de7e 100644 --- a/src/dawn/poker/Card.cpp +++ b/src/dawn/poker/Card.cpp @@ -13,6 +13,7 @@ void Card::fillDeck(std::vector *deck) { } } + void Card::sort(std::vector *deck) { std::sort(deck->begin(), deck->end(), &cardSorter); } diff --git a/src/dawn/poker/Card.hpp b/src/dawn/poker/Card.hpp index 41933ed3..c3713486 100644 --- a/src/dawn/poker/Card.hpp +++ b/src/dawn/poker/Card.hpp @@ -45,6 +45,11 @@ namespace Dawn { static void fillDeck(std::vector *deck); static void shuffle(std::vector *deck); + static bool_t contains(std::vector *deck, struct Card); + static std::vector countPairs( + std::vector *deck, + enum CardValue value + ); /** * Sort a hand of cards. Cards are ordered in descending weight, aces are @@ -58,9 +63,12 @@ namespace Dawn { Card(CardSuit suit, CardValue num) : cardValue((suit * CARD_COUNT_PER_SUIT) + num) { + assertTrue(suit < CARD_SUIT_COUNT); + assertTrue(num < CARD_COUNT_PER_SUIT); } Card(uint8_t cv) : cardValue(cv) { + assertTrue(cv < CARD_DECK_SIZE); } CardValue getValue() { diff --git a/src/dawn/poker/PokerPlayer.cpp b/src/dawn/poker/PokerPlayer.cpp index 176e2537..1a524799 100644 --- a/src/dawn/poker/PokerPlayer.cpp +++ b/src/dawn/poker/PokerPlayer.cpp @@ -239,6 +239,7 @@ int32_t PokerPlayer::getSumOfChips() { struct PokerWinning PokerPlayer::getWinning() { struct PokerWinning winning; + uint8_t i, j, l; // Get the full poker hand (should be a 7 card hand, but MAY not be) auto itHand = this->hand.begin(); @@ -260,78 +261,89 @@ struct PokerWinning PokerPlayer::getWinning() { auto it = winning.full.begin(); while(it != winning.full.end()) { auto number = it->getValue(); + auto suit = it->getSuit(); if(number < CARD_FIVE) { ++it; continue; } - auto suit = it->getSuit(); - winning->setSize = 1; + winning.set.clear(); + winning.set.push_back(*it); // Now look for the matching cards (Reverse order to order from A to 10) for(j = 1; j <= 4; j++) { l = number == CARD_FIVE && j == 4 ? CARD_ACE : number - j;//Ace low. - index = cardContains(winning->full, winning->fullSize, cardGet(l, suit)); - if(index == -1) break; - winning->set[j] = winning->full[index]; - winning->setSize++; + auto c = Card(suit, (CardValue)l); + if(!Card::contains(&winning.full, c)) break; + winning.set.push_back(c); } // Check if has all necessary cards. - if(winning->setSize < POKER_WINNING_SET_SIZE) continue; + if(winning.set.size() != 5) { + ++it; + continue; + } // Add self to array - winning->set[0] = winning->full[i]; - winning->type = ( + winning.type = ( number == CARD_ACE ? POKER_WINNING_TYPE_ROYAL_FLUSH : POKER_WINNING_TYPE_STRAIGHT_FLUSH ); pokerWinnerFillRemaining(winning); - return; + return winning; } // Four of a kind. - winning->setSize = 0; - for(i = 0; i < winning->fullSize; i++) { - card = winning->full[i]; - number = cardGetNumber(card); - pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs); - if(pairCount < CARD_SUIT_COUNT) continue; - - winning->setSize = pairCount; - for(j = 0; j < pairCount; j++) winning->set[j] = winning->full[pairs[j]]; - winning->type = POKER_WINNING_TYPE_FOUR_OF_A_KIND; - pokerWinnerFillRemaining(winning); - return; - } - - // Full House - winning->setSize = 0; - for(i = 0; i < winning->fullSize; i++) { - // Check we haven't already added this card. - card = winning->full[i]; - if(winning->setSize > 0 && (winning->set, winning->setSize, card) != -1) { + it = winning.full.begin(); + while(it != winning.full.end()) { + auto pairs = Card::countPairs(&winning.full, it->getValue()); + if(pairs.size() < CARD_SUIT_COUNT) { + ++it; continue; } - number = cardGetNumber(card); - pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs); + winning.set = pairs; + winning.type = POKER_WINNING_TYPE_FOUR_OF_A_KIND; + pokerWinnerFillRemaining(winning); + return winning; + } + + // Full House + winning.set.clear(); + it = winning.full.begin(); + while(it != winning.full.end()) { + // Check we haven't already added this card. + if(Card::contains(&winning.set, *it) != -1) { + ++it; + continue; + } + + auto pairs = Card::countPairs(&winning.full, it->getValue()); // Did we find either two pair or three pair? - if(pairCount != 2 && pairCount != 3) continue; - if(winning->setSize == 3) pairCount = 2;//Clamp to 5 max. + if(pairs.size() != 2 && pairs.size() != 3) { + ++it; + continue; + } + if(winning.set.size() == 3) { + winning.set.pop_back(); + } // Copy found pairs. - for(j = 0; j < pairCount; j++) { - winning->set[winning->setSize + j] = winning->full[pairs[j]]; + auto itPairs = pairs.begin(); + while(itPairs != pairs.end()) { + winning.set.push_back(*itPairs); + ++itPairs; } - winning->setSize += pairCount; // Winned? - if(winning->setSize != POKER_WINNING_SET_SIZE) continue; - winning->type = POKER_WINNING_TYPE_FULL_HOUSE; + if(winning.set.size() != 5) { + ++it; + continue; + } + winning.type = POKER_WINNING_TYPE_FULL_HOUSE; pokerWinnerFillRemaining(winning); - return; + return winning; } // Flush (5 same suit) diff --git a/src/dawn/poker/PokerWinning.hpp b/src/dawn/poker/PokerWinning.hpp index 65904817..cbca6bf3 100644 --- a/src/dawn/poker/PokerWinning.hpp +++ b/src/dawn/poker/PokerWinning.hpp @@ -37,6 +37,7 @@ namespace Dawn { public: enum PokerWinningType type; std::vector full; + std::vector set; static float_t getWinningTypeConfidence(enum PokerWinningType type); };