Moved winning hand solver code to player.c

This commit is contained in:
2021-06-24 15:06:13 -07:00
parent 58dbfc65dd
commit 0ec6087bd0
5 changed files with 263 additions and 235 deletions

View File

@ -36,4 +36,208 @@ void pokerPlayerDealAll(poker_t *poker, uint8_t count) {
pokerPlayerDeal(poker, player);
}
}
}
void pokerPlayerGetFullHand(poker_t *poker,pokerplayer_t *player,card_t *cards){
uint8_t i;
// Add the dealer hand
for(i = 0; i < poker->cardsFacing; i++) {
cards[i] = poker->cards[i];
}
// Add the player hand
for(i = 0; i < player->cardCount; i++) {
cards[i+poker->cardsFacing] = player->cards[i];
}
// Sort by card value
cardHandSort(cards, poker->cardsFacing+player->cardCount);
}
pokerwinning_t pokerPlayerGetWinning(poker_t *poker, pokerplayer_t *player) {
pokerwinning_t winning;
uint8_t i, j, l;
int32_t index;
card_t card;
uint8_t number, suit, pairCount;
int32_t pairs[CARD_SUIT_COUNT];
// Get the full poker hand (should be a 7 card hand)
winning.size = poker->cardsFacing + player->cardCount;
pokerPlayerGetFullHand(poker, player, winning.full);
// Reset the winning status.
winning.count = 0;
winning.type = 0x00;
for(i = 0; i < POKER_WINNING_SET_SIZE; i++) winning.set[i] = -1;
//////////////////////// Now look for the winning set ////////////////////////
// Royal / Straight Flush
for(i = 0; i < winning.size; i++) {
card = winning.full[i];
number = cardGetNumber(card);
if(number < CARD_FIVE) continue;
suit = cardGetSuit(card);
winning.count = 1;
// 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.size, cardGet(l, suit));
if(index == -1) break;
winning.set[j] = index;
winning.count++;
}
// Check if has all necessary cards.
if(winning.count < POKER_WINNING_SET_SIZE) continue;
// Add self to array
winning.set[0] = i;
winning.type = (
number == CARD_ACE ? POKER_WINNING_TYPE_ROYAL_FLUSH :
POKER_WINNING_TYPE_STRAIGHT_FLUSH
);
return winning;
}
// Four of a kind.
winning.count = 0;
for(i = 0; i < winning.size; i++) {
card = winning.full[i];
number = cardGetNumber(card);
pairCount = cardCountPairs(winning.full, winning.size, number, pairs);
if(pairCount < CARD_SUIT_COUNT) continue;
winning.count = pairCount;
arrayCopy(sizeof(int32_t), pairs, pairCount, winning.set);
winning.type = POKER_WINNING_TYPE_FOUR_OF_A_KIND;
pokerPlayerWinningFillRemaining(&winning);
return winning;
}
// Full House
winning.count = 0;
for(i = 0; i < winning.size; i++) {
index = i;// Check we haven't already added this card.
if(arrayContains(sizeof(int32_t),winning.set,winning.count,&index))continue;
card = winning.full[i];
number = cardGetNumber(card);
pairCount = cardCountPairs(winning.full, winning.size, number, pairs);
// Did we find either two pair or three pair?
if(pairCount != 2 && pairCount != 3) continue;
if(winning.count == 3) pairCount = 2;//Clamp to 5 max.
arrayCopy(sizeof(int32_t), pairs, pairCount, winning.set+winning.count);
winning.count += pairCount;
if(winning.count != POKER_WINNING_SET_SIZE) continue;
winning.type = POKER_WINNING_TYPE_FULL_HOUSE;
printf("Full House\n");
return winning;
}
// Flush (5 same suit)
for(i = 0; i < winning.size; i++) {
card = winning.full[i];
suit = cardGetSuit(card);
winning.count = 1;
for(j = i+1; j < winning.size; j++) {
if(cardGetSuit(winning.full[j]) != suit) continue;
winning.set[winning.count] = j;
winning.count++;
if(winning.count == POKER_WINNING_SET_SIZE) break;
}
if(winning.count < POKER_WINNING_SET_SIZE) continue;
winning.set[0] = i;
winning.type = POKER_WINNING_TYPE_FLUSH;
return winning;
}
// Straight (sequence any suit)
winning.count = 0;
for(i = 0; i < winning.size; i++) {
card = winning.full[i];
number = cardGetNumber(card);
if(number < CARD_FIVE) continue;
winning.count = 1;
for(j = 1; j <= 4; j++) {
l = number == CARD_FIVE && j == 4 ? CARD_ACE : number - j;//Ace low.
index = cardContainsNumber(winning.full, winning.size, l);
if(index == -1) break;
winning.set[j] = index;
winning.count++;
}
// Check if has all necessary cards.
if(winning.count < POKER_WINNING_SET_SIZE) continue;
winning.set[0] = i;
winning.type = POKER_WINNING_TYPE_STRAIGHT;
return winning;
}
// Three of a kind
winning.count = 0;
for(i = 0; i < winning.size; i++) {
card = winning.full[i];
number = cardGetNumber(card);
pairCount = cardCountPairs(winning.full, winning.size, number, pairs);
if(pairCount != 3) continue;
winning.count = pairCount;
arrayCopy(sizeof(int32_t), pairs, pairCount, winning.set);
winning.type = POKER_WINNING_TYPE_THREE_OF_A_KIND;
pokerPlayerWinningFillRemaining(&winning);
return winning;
}
// Two Pair
winning.count = 0;
for(i = 0; i < winning.size; i++) {
index = i;// Check we haven't already added this card.
if(arrayContains(sizeof(int32_t),winning.set,winning.count,&index))continue;
card = winning.full[i];
number = cardGetNumber(card);
pairCount = cardCountPairs(winning.full, winning.size, number, pairs);
if(pairCount != 2) continue;
arrayCopy(sizeof(int32_t), pairs, pairCount, winning.set+winning.count);
winning.count += pairCount;
if(winning.count != 4) continue;
winning.type = POKER_WINNING_TYPE_TWO_PAIR;
pokerPlayerWinningFillRemaining(&winning);
return winning;
}
// Pair
if(winning.count == 2) {
winning.type = POKER_WINNING_TYPE_PAIR;
pokerPlayerWinningFillRemaining(&winning);
return winning;
}
// High card
winning.count = 0;
pokerPlayerWinningFillRemaining(&winning);
winning.type = POKER_WINNNIG_TYPE_HIGH_CARD;
return winning;
}
void pokerPlayerWinningFillRemaining(pokerwinning_t *winning) {
uint8_t i;
int32_t index;
for(i = winning->count; i < POKER_WINNING_SET_SIZE; i++) {
if(arrayContains(sizeof(int32_t),winning->set,winning->count,&i)) continue;
winning->set[winning->count++] = i;
}
arraySortInt32(winning->set, winning->count);
}