Refactor round 1

This commit is contained in:
2021-07-12 15:04:10 -07:00
parent 223f5be854
commit 8b45b976d4
24 changed files with 653 additions and 508 deletions

View File

@ -38,12 +38,14 @@
#include "input/input.h"
// Poker Game Logic
#include "poker/bet.h"
#include "poker/card.h"
#include "poker/chip.h"
#include "poker/dealer.h"
#include "poker/player.h"
#include "poker/poker.h"
#include "poker/render.h"
#include "poker/strings.h"
#include "poker/winner.h"
// Utility Objects
#include "util/array.h"

26
include/dawn/poker/bet.h Normal file
View File

@ -0,0 +1,26 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
/** How many chips each player has by defautl */
#define POKER_BET_PLAYER_CHIPS_DEFAULT 10000
/** The default blind cost for the big blind. */
#define POKER_BET_BLIND_BIG_DEFAULT 600
/** The default blind cost for the small blind. (Defaults half big blind) */
#define POKER_BET_BLIND_SMALL_DEFAULT (POKER_BET_BLIND_BIG_DEFAULT/2)
typedef struct {
/** Blinds */
uint32_t blindSmall, blindBig;
/** Current pot of chips */
uint32_t pot;
} pokerbet_t;

View File

@ -1,8 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once

View File

@ -0,0 +1,27 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "card.h"
#include "../display/texture.h"
#include "../display/tileset.h"
#include "../display/primitive.h"
/** How many cards the dealer can hold in their hand */
#define POKER_DEALER_HAND 5
/** Representation of the dealer state */
typedef struct {
/** Dealer Hand */
card_t cards[POKER_DEALER_HAND];
uint8_t cardsFacing;
texture_t dealerTexture;
tileset_t dealerTileset;
primitive_t dealerPrimitive;
} pokerdealer_t;

View File

@ -7,14 +7,24 @@
#pragma once
#include "../libs.h"
#include "bet.h"
#include "dealer.h"
#include "card.h"
#include "../display/texture.h"
#include "../display/primitive.h"
#include "../display/tileset.h"
/** How many cards a player can hold in their hand */
#define POKER_PLAYER_HAND 2
/** How many players in a poker game (excludes dealer) */
#define POKER_PLAYER_COUNT 5
////////////////////////////////////////////////////////////////////////////////
// Player States
////////////////////////////////////////////////////////////////////////////////
/** State for whether or not a player has folded */
#define POKER_PLAYER_STATE_FOLDED 0x01
@ -27,6 +37,11 @@
/** The index that the player who is the human... is */
#define POKER_PLAYER_HUMAN_INDEX 0x02
////////////////////////////////////////////////////////////////////////////////
// Player Definition
////////////////////////////////////////////////////////////////////////////////
/** Poker Player State */
typedef struct {
/** Cards in the players' hand */
@ -42,10 +57,11 @@ typedef struct {
/** Current bet in current round player has placed */
uint32_t currentBet;
// Rendering assets
texture_t bodyTexture;
primitive_t bodyPrimitive;
texture_t faceTexture;
primitive_t facePrimitive;
primitive_t facePrimitive;
} pokerplayer_t;

View File

@ -7,15 +7,19 @@
#pragma once
#include "../libs.h"
#include "bet.h"
#include "dealer.h"
#include "player.h"
#include "card.h"
#include "render.h"
#include "winner.h"
#include "../display/camera.h"
#include "../display/shader.h"
#include "../display/texture.h"
#include "../display/tileset.h"
#include "../display/framebuffer.h"
#include "../display/primitive.h"
/** Rounds that the game can be in */
#define POKER_ROUND_MATCH 0x00
@ -31,22 +35,9 @@
#define POKER_ROUND_BET3 0x0A
#define POKER_ROUND_WINNER 0x0B
/** How many cards the dealer can hold in their hand */
#define POKER_DEALER_HAND 5
/** How many cards the grave can hold */
#define POKER_GRAVE_SIZE CARD_DECK_SIZE
/** How many players in a poker game (excludes dealer) */
#define POKER_PLAYER_COUNT 5
/** How many chips each player has by defautl */
#define POKER_PLAYER_CHIPS_DEFAULT 10000
/** The default blind cost for the big blind. Small Blind is half this */
#define POKER_BLIND_BIG_DEFAULT 600
#define POKER_BLIND_SMALL_DEFAULT (POKER_BLIND_BIG_DEFAULT/2)
/** GUI Height fix (To keep gui scaling nicely we use a fixed height) */
#define POKER_GUI_HEIGHT 2160
@ -57,44 +48,10 @@
#define POKER_TURN_CARD_COUNT 1
#define POKER_RIVER_CARD_COUNT 1
/** Winning Types */
#define POKER_WINNING_TYPE_NULL 0x00
#define POKER_WINNING_TYPE_ROYAL_FLUSH 0x01
#define POKER_WINNING_TYPE_STRAIGHT_FLUSH 0x02
#define POKER_WINNING_TYPE_FOUR_OF_A_KIND 0x03
#define POKER_WINNING_TYPE_FULL_HOUSE 0x04
#define POKER_WINNING_TYPE_FLUSH 0x05
#define POKER_WINNING_TYPE_STRAIGHT 0x06
#define POKER_WINNING_TYPE_THREE_OF_A_KIND 0x07
#define POKER_WINNING_TYPE_TWO_PAIR 0x08
#define POKER_WINNING_TYPE_PAIR 0x09
#define POKER_WINNNIG_TYPE_HIGH_CARD 0x0A
/** How many cards make a winning set */
#define POKER_WINNING_SET_SIZE 5
/** Holds information about the winning player state */
typedef struct {
/** The full set of both the dealer and player's hand */
card_t full[POKER_PLAYER_HAND + POKER_DEALER_HAND];
uint8_t fullSize;
/** Holds the winning set */
card_t set[POKER_WINNING_SET_SIZE];
uint8_t setSize;
/** Winning Type */
uint8_t type;
/** If there was a kicker card it will be here, otherwise -1 for no kicker */
card_t kicker;
} pokerwinning_t;
typedef struct {
//////////////////////////////////////////////////////////////////////////////
// Poker Logic Variables
//////////////////////////////////////////////////////////////////////////////
/** Current Card Deck */
card_t deck[CARD_DECK_SIZE];
uint8_t deckSize;
@ -103,50 +60,44 @@ typedef struct {
card_t grave[POKER_GRAVE_SIZE];
uint8_t graveSize;
/** Blinds */
uint32_t blindSmall, blindBig;
/** Dealer Hand */
card_t cards[POKER_DEALER_HAND];
uint8_t cardsFacing;
/** Poker betting state */
pokerbet_t bet;
/** Player States */
pokerdealer_t dealer;
pokerplayer_t players[POKER_PLAYER_COUNT];
/** Winning States */
pokerwinning_t winnings[POKER_PLAYER_COUNT];
uint8_t winners[POKER_PLAYER_COUNT];
uint8_t winnerCount;
/** The current round the game is on */
uint8_t round;
pokerwinner_t winner;
/** The current player that is the dealer */
uint8_t roundDealer;
uint8_t roundSmallBlind;
uint8_t roundBigBlind;
/** Current pot of chips */
uint32_t pot;
//////////////////////////////////////////////////////////////////////////////
// Round variables
//////////////////////////////////////////////////////////////////////////////
uint32_t roundTextCounter;
/** The current round the game is on */
uint8_t round;
/** For Betting round, which player is currently betting */
uint8_t roundBetCurrent;
uint32_t roundTextCounter;
//////////////////////////////////////////////////////////////////////////////
// Rendering Variables
//////////////////////////////////////////////////////////////////////////////
/** Frames to hold the world and GUI render outputs */
framebuffer_t frameWorld, frameGui;
/** Game's Font */
font_t font;
/** Game's Shader */
shader_t shader;
/** Camera for the world and the GUI */
camera_t cameraWorld, cameraGui, cameraTest;
@ -162,19 +113,6 @@ typedef struct {
/** Information about the current rendered text */
fonttextinfo_t *talkTextInfo;
/** Match Scene Variables */
float matchStart;
texture_t dealerTexture;
tileset_t dealerTileset;
primitive_t dealerPrimitive;
texture_t chipTexture;
primitive_t chipPrimitive;

View File

@ -0,0 +1,54 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "player.h"
#include "dealer.h"
/** Size of the FULL hand used to calculate a winning. */
#define POKER_WINNING_FULL_SIZE POKER_PLAYER_HAND+POKER_DEALER_HAND
/** How many cards make a winning set */
#define POKER_WINNING_SET_SIZE 5
/** Winning Types */
#define POKER_WINNING_TYPE_NULL 0x00
#define POKER_WINNING_TYPE_ROYAL_FLUSH 0x01
#define POKER_WINNING_TYPE_STRAIGHT_FLUSH 0x02
#define POKER_WINNING_TYPE_FOUR_OF_A_KIND 0x03
#define POKER_WINNING_TYPE_FULL_HOUSE 0x04
#define POKER_WINNING_TYPE_FLUSH 0x05
#define POKER_WINNING_TYPE_STRAIGHT 0x06
#define POKER_WINNING_TYPE_THREE_OF_A_KIND 0x07
#define POKER_WINNING_TYPE_TWO_PAIR 0x08
#define POKER_WINNING_TYPE_PAIR 0x09
#define POKER_WINNNIG_TYPE_HIGH_CARD 0x0A
/** Holds information about a player's winning state */
typedef struct {
/** The full set of both the dealer and player's hand */
card_t full[POKER_WINNING_FULL_SIZE];
uint8_t fullSize;
/** Holds the winning set */
card_t set[POKER_WINNING_SET_SIZE];
uint8_t setSize;
/** Winning Type */
uint8_t type;
/** If there was a kicker card it will be here, otherwise -1 for no kicker */
card_t kicker;
} pokerplayerwinning_t;
typedef struct {
/** Winning States */
pokerplayerwinning_t winnings[POKER_PLAYER_COUNT];
uint8_t winners[POKER_PLAYER_COUNT];
uint8_t winnerCount;
} pokerwinner_t;

23
src/poker/bet.c Normal file
View File

@ -0,0 +1,23 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "bet.h"
void pokerBetPlayer(poker_t *poker, pokerplayer_t *player, int32_t chips) {
poker->bet.pot += chips;
player->chips -= chips;
player->currentBet += chips;
}
void pokerBetTakeBlinds(poker_t *poker) {
pokerBetPlayer(poker, poker->players + poker->roundSmallBlind,
poker->bet.blindSmall
);
pokerBetPlayer(poker, poker->players + poker->roundBigBlind,
poker->bet.blindBig
);
}

23
src/poker/bet.h Normal file
View File

@ -0,0 +1,23 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include <dawn/dawn.h>
/**
* Let a player bet chips into the pot.
*
* @param poker Poker game instance.
* @param player Poker player instance.
* @param chips Chips to bet.
*/
void pokerBetPlayer(poker_t *poker, pokerplayer_t *player, int32_t chips);
/**
* Takes the current blinds from the correct players.
*
* @param poker Poker game to take the blinds from.
*/
void pokerBetTakeBlinds(poker_t *poker);

View File

@ -45,6 +45,8 @@ void cardDeal(card_t *source, uint8_t *sourceSize, card_t *dest,
/**
* Sort a hand of cards. Cards are ordered in descending weight, aces are high.
* Cards will be grouped by their suits, e.g. CARD_CLUBS_TWO will appear before
* CARD_DIAMONDS_KING.
*
* @param cards Hand of cards to sort.
* @param length Length of the array of cards.

17
src/poker/dealer.c Normal file
View File

@ -0,0 +1,17 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "dealer.h"
void pokerDealerDeal(poker_t *poker, uint8_t count) {
uint8_t i;
for(i = 0; i < count; i++) {
cardDeal(
poker->deck, &poker->deckSize,
poker->dealer.cards, &poker->dealer.cardsFacing
);
}
}

17
src/poker/dealer.h Normal file
View File

@ -0,0 +1,17 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include <dawn/dawn.h>
#include "card.h"
/**
* Deals cards to each player from the dealers' deck. Cards are dealt one to
* each player $count times.
*
* @param poker Poker game instance
* @param count Count of cards to deal.
*/
void pokerDealerDeal(poker_t *poker, uint8_t count);

View File

@ -7,12 +7,6 @@
#include "player.h"
void pokerPlayerBet(poker_t *poker, pokerplayer_t *player, int32_t chips) {
poker->pot += chips;
player->chips -= chips;
player->currentBet += chips;
}
bool pokerPlayerIsAlive(pokerplayer_t *player) {
return !(player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT));
}
@ -36,340 +30,4 @@ 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);
}
void 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->fullSize = poker->cardsFacing + player->cardCount;
pokerPlayerGetFullHand(poker, player, winning->full);
// Reset the winning status.
winning->setSize = 0;
//////////////////////// Now look for the winning set ////////////////////////
// Royal / Straight Flush
for(i = 0; i < winning->fullSize; i++) {
card = winning->full[i];
number = cardGetNumber(card);
if(number < CARD_FIVE) continue;
suit = cardGetSuit(card);
winning->setSize = 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->fullSize, cardGet(l, suit));
if(index == -1) break;
winning->set[j] = winning->full[index];
winning->setSize++;
}
// Check if has all necessary cards.
if(winning->setSize < POKER_WINNING_SET_SIZE) continue;
// Add self to array
winning->set[0] = winning->full[i];
winning->type = (
number == CARD_ACE ? POKER_WINNING_TYPE_ROYAL_FLUSH :
POKER_WINNING_TYPE_STRAIGHT_FLUSH
);
return;
}
// 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;
pokerPlayerWinningFillRemaining(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(cardContains(winning->set, winning->setSize, card) != -1) continue;
number = cardGetNumber(card);
pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs);
// 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.
// Copy found pairs.
for(j = 0; j < pairCount; j++) {
winning->set[winning->setSize + j] = winning->full[pairs[j]];
}
winning->setSize += pairCount;
// Winned?
if(winning->setSize != POKER_WINNING_SET_SIZE) continue;
winning->type = POKER_WINNING_TYPE_FULL_HOUSE;
printf("Full House\n");
return;
}
// Flush (5 same suit)
for(i = 0; i < winning->fullSize; i++) {
card = winning->full[i];
suit = cardGetSuit(card);
winning->setSize = 1;
for(j = i+1; j < winning->fullSize; j++) {
if(cardGetSuit(winning->full[j]) != suit) continue;
winning->set[winning->setSize] = winning->full[j];
winning->setSize++;
if(winning->setSize == POKER_WINNING_SET_SIZE) break;
}
if(winning->setSize < POKER_WINNING_SET_SIZE) continue;
winning->set[0] = winning->full[0];
winning->type = POKER_WINNING_TYPE_FLUSH;
return;
}
// Straight (sequence any suit)
winning->setSize = 0;
for(i = 0; i < winning->fullSize; i++) {
card = winning->full[i];
number = cardGetNumber(card);
if(number < CARD_FIVE) continue;
winning->setSize = 1;
for(j = 1; j <= 4; j++) {
l = number == CARD_FIVE && j == 4 ? CARD_ACE : number - j;//Ace low.
index = cardContainsNumber(winning->full, winning->fullSize, l);
if(index == -1) break;
winning->set[j] = winning->full[index];
winning->setSize++;
}
// Check if has all necessary cards.
if(winning->setSize < POKER_WINNING_SET_SIZE) continue;
winning->set[0] = winning->full[i];
winning->type = POKER_WINNING_TYPE_STRAIGHT;
return;
}
// Three 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 != 3) continue;
winning->setSize = pairCount;
for(j = 0; j < pairCount; j++) winning->set[j] = winning->full[pairs[j]];
winning->type = POKER_WINNING_TYPE_THREE_OF_A_KIND;
pokerPlayerWinningFillRemaining(winning);
return;
}
// Two Pair
winning->setSize = 0;
for(i = 0; i < winning->fullSize; i++) {
card = winning->full[i];// Check we haven't already added this card.
if(cardContains(winning->set, winning->setSize, card) != -1) {
continue;
}
number = cardGetNumber(card);
pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs);
if(pairCount != 2) continue;
for(j = 0; j < pairCount; j++) {
winning->set[j] = winning->full[winning->setSize + pairs[j]];
}
// arrayCopy(sizeof(int32_t), pairs, pairCount, winning->set+winning->setSize);
winning->setSize += pairCount;
if(winning->setSize != 4) continue;
winning->type = POKER_WINNING_TYPE_TWO_PAIR;
pokerPlayerWinningFillRemaining(winning);
return;
}
// Pair
if(winning->setSize == 2) {
winning->type = POKER_WINNING_TYPE_PAIR;
pokerPlayerWinningFillRemaining(winning);
return;
}
// High card
winning->setSize = 0;
pokerPlayerWinningFillRemaining(winning);
winning->type = POKER_WINNNIG_TYPE_HIGH_CARD;
return;
}
void pokerPlayerWinningFillRemaining(pokerwinning_t *winning) {
uint8_t i, highest, current;
card_t highestCard, currentCard;
// Set the kicker
winning->kicker = 0xFF;
// Fill the remaining cards
while(winning->setSize < POKER_WINNING_SET_SIZE) {
highest = 0xFF;
for(i = 0; i < winning->fullSize; i++) {
currentCard = winning->full[i];
if(cardContains(winning->set, winning->setSize, currentCard) != -1) {
continue;
}
if(highest == 0xFF) {
highestCard = currentCard;
highest = cardGetNumber(highestCard);
} else {
current = cardGetNumber(currentCard);
if(current != CARD_ACE && current < highest) continue;
highestCard = currentCard;
highest = current;
}
}
winning->set[winning->setSize++] = highestCard;
}
cardHandSort(winning->set, winning->setSize);
}
card_t pokerPlayerCompareWinning(pokerwinning_t *left, pokerwinning_t *right) {
uint8_t i, number;
card_t card;
int32_t index;
card_t highCardLeft, highCardRight;
uint8_t highNumberLeft, highNumberRight;
highNumberLeft = 0xFF;
highNumberRight = 0xFF;
for(i = 0; i < left->setSize; i++) {
card = left->set[i];
number = cardGetNumber(card);
if(highNumberLeft != 0xFF && number < highNumberLeft) continue;// Quick check
index = cardContainsNumber(right->set, right->setSize, number);
if(index != -1) continue;// In other?
if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberRight < number) {
highNumberLeft = number;
highCardLeft = card;
}
}
for(i = 0; i < right->setSize; i++) {
card = right->set[i];
number = cardGetNumber(card);
if(highNumberRight != 0xFF && number < highNumberRight) continue;
index = cardContainsNumber(left->set, left->setSize, number);
if(index != -1) continue;
if(highNumberRight == 0xFF||number == CARD_ACE||highNumberRight < number) {
highNumberRight = number;
highCardRight = card;
}
}
if(highNumberLeft < highNumberRight) return 0xFF;
return highCardLeft;//Greater or Equal to.
}
void pokerPlayerWinnerDetermine(poker_t *poker) {
uint8_t i, j, number, highNumber;
pokerwinning_t *left, *right;
pokerplayer_t *player;
card_t card, highCard;
bool winner;
poker->winnerCount = 0;
// Get winning sets
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
left = poker->winnings + i;
left->type = POKER_WINNING_TYPE_NULL;
player = poker->players + i;
if(!pokerPlayerIsAlive(player)) continue;
// Get the players' full hand.
pokerPlayerGetWinning(poker, player, left);
}
// Compare against each player
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
left = poker->winnings + i;
if(left->type == POKER_WINNING_TYPE_NULL) continue;
winner = true;
highNumber = 0xFF;
for(j = 0; j < POKER_PLAYER_COUNT; j++) {
if(i == j) continue;
right = poker->winnings + j;
if(right->type == POKER_WINNING_TYPE_NULL) continue;
// Am I the better hand / Is it the better hand?
if(left->type < right->type) continue;
if(left->type > right->type) {
winner = false;
break;
}
// Equal, compare hands.
card = pokerPlayerCompareWinning(left, right);
if(card == 0xFF) {
winner = false;
break;
}
// Determine high card.
number = cardGetNumber(card);
if(highNumber == 0xFF || number == CARD_ACE || number > highNumber) {
highCard = card;
highNumber = number;
}
}
if(!winner) continue;
left->kicker = highCard;
poker->winners[poker->winnerCount++] = i;
}
}
}

View File

@ -8,15 +8,6 @@
#include <dawn/dawn.h>
#include "card.h"
/**
* Let a player bet chips into the pot.
*
* @param poker Poker game instance.
* @param player Poker player instance.
* @param chips Chips to bet.
*/
void pokerPlayerBet(poker_t *poker, pokerplayer_t *player, int32_t chips);
/**
* Returns true if the player is still alive and in the current game/
* Defined as: Not out, not folded.
@ -49,50 +40,4 @@ void pokerPlayerDeal(poker_t *poker, pokerplayer_t *player);
* @param poker Poker game instance.
* @param count Count of cards to deal.
*/
void pokerPlayerDealAll(poker_t *poker, uint8_t count);
/**
* Returns the full hand for a given player including the best cards on the
* bench.
*
* @param poker Poker game instance.
* @param player Poker player game instance.
* @param cards Array of at least 7 length to store the array.
*/
void pokerPlayerGetFullHand(poker_t *poker,pokerplayer_t *player,card_t *cards);
/**
* Calculates and returns the winning state for a given player
*
* @param poker Poker game instance.
* @param player Player game instance.
* @param winning Pointer to the poker winning to fill out.
* @return The winning state for this player.
*/
void pokerPlayerGetWinning(
poker_t *poker, pokerplayer_t *player, pokerwinning_t *winning
);
/**
* Fills the remaining cards for a given poker player winning hand.
* @param winning Pointer to the poker winning to fill out.
*/
void pokerPlayerWinningFillRemaining(pokerwinning_t *winning);
/**
* Compares two winning sets. The returned card is the kicker if the LEFT side
* is the winner. If LEFT is not a winner then 0xFF will be returned.
*
* @param left Left winning set.
* @param right Right winning set.
* @return The kicker card from left's hand or 0xFF if left is not the winner.
*/
card_t pokerPlayerCompareWinning(pokerwinning_t *left, pokerwinning_t *right);
/**
* Determines the winning player for the game. Values will be stored back into
* the poker winning state.
*
* @param poker Poker game instance.
*/
void pokerPlayerWinnerDetermine(poker_t *poker);
void pokerPlayerDealAll(poker_t *poker, uint8_t count);

View File

@ -12,8 +12,7 @@ void pokerBlindsInit(poker_t *poker) {
poker->round = POKER_ROUND_BLINDS;
// Now take blinds
pokerPlayerBet(poker,poker->players+poker->roundSmallBlind, poker->blindSmall);
pokerPlayerBet(poker,poker->players+poker->roundBigBlind, poker->blindBig);
pokerBetTakeBlinds(poker);
printf("Blinds Taken\n");
pokerDealInit(poker);

View File

@ -7,7 +7,7 @@
#include <dawn/dawn.h>
#include "deal.h"
#include "../player.h"
#include "../bet.h"
/**
* Initializes the blinds round.

View File

@ -8,7 +8,7 @@
#include "flop.h"
void pokerFlopInit(poker_t *poker) {
uint8_t count, i;
uint8_t count;
if(poker->round == POKER_ROUND_BET0) {
printf("Poker Flop Start\n");
@ -28,12 +28,7 @@ void pokerFlopInit(poker_t *poker) {
poker->deckSize--;
// Flops
for(i = 0; i < count; i++) {
cardDeal(
poker->deck, &poker->deckSize,
poker->cards, &poker->cardsFacing
);
}
pokerDealerDeal(poker, count);
pokerBetInit(poker);
}

View File

@ -7,7 +7,7 @@
#pragma once
#include <dawn/dawn.h>
#include "bet.h"
#include "../dealer.h"
#include "../card.h"
void pokerFlopInit(poker_t *poker);

View File

@ -10,24 +10,24 @@ void pokerMatchInit(poker_t *poker, engine_t *engine) {
uint8_t x;
// Look at the dealer
poker->matchStart = engine->time.current;
// poker->matchStart = engine->time.current;
pokerLookAtPlayer(&poker->cameraWorld, POKER_SEAT_DEALER, 100);
// Reset the main game state. This does not init the round.
poker->blindBig = POKER_BLIND_BIG_DEFAULT;
poker->blindSmall = POKER_BLIND_SMALL_DEFAULT;
poker->bet.blindBig = POKER_BET_BLIND_BIG_DEFAULT;
poker->bet.blindSmall = POKER_BET_BLIND_SMALL_DEFAULT;
poker->roundDealer = POKER_PLAYER_COUNT-2;
poker->roundTextCounter = 0;
poker->round = POKER_ROUND_MATCH;
for(x = 0; x < POKER_PLAYER_COUNT; x++) {
poker->players[x].state = 0x00;
poker->players[x].chips = POKER_PLAYER_CHIPS_DEFAULT;
poker->players[x].chips = POKER_BET_PLAYER_CHIPS_DEFAULT;
}
printf("Match Start\n");
// pokerStartInit(poker);
}
void pokerMatchUpdate(poker_t *poker, engine_t *engine) {
float matchDiff = poker->matchStart - engine->time.current;
// float matchDiff = poker->matchStart - engine->time.current;
}

View File

@ -16,9 +16,9 @@ void pokerStartInit(poker_t *poker) {
// Prepare the initial game state
poker->round = POKER_ROUND_DEAL;
poker->pot = 0;
poker->bet.pot = 0;
poker->graveSize = 0;
poker->cardsFacing = 0;
poker->dealer.cardsFacing = 0;
poker->deckSize = CARD_DECK_SIZE;
for(i = 0; i < CARD_DECK_SIZE; i++) poker->deck[i] = i;

View File

@ -7,6 +7,6 @@
#include "winner.h"
void pokerWinnerInit(poker_t *poker) {
pokerPlayerWinnerDetermine(poker);
printf("Winner Count %u\n", poker->winnerCount);
pokerWinnerCalculate(poker);
printf("Winner Count %u\n", poker->winner.winnerCount);
}

View File

@ -8,5 +8,6 @@
#pragma once
#include <dawn/dawn.h>
#include "../player.h"
#include "../winner.h"
void pokerWinnerInit(poker_t *poker);

348
src/poker/winner.c Normal file
View File

@ -0,0 +1,348 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "winner.h"
void pokerWinnerHandGetFull(poker_t *poker, pokerplayer_t *player,
card_t *cards
){
uint8_t i;
// Add the dealer hand
for(i = 0; i < poker->dealer.cardsFacing; i++) {
cards[i] = poker->dealer.cards[i];
}
// Add the player hand
for(i = 0; i < player->cardCount; i++) {
cards[i+poker->dealer.cardsFacing] = player->cards[i];
}
// Sort by card value
cardHandSort(cards, poker->dealer.cardsFacing + player->cardCount);
}
void pokerWinnerPlayerGet(
poker_t *poker, pokerplayer_t *player, pokerplayerwinning_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, but MAY not be)
winning->fullSize = poker->dealer.cardsFacing + player->cardCount;
pokerWinnerHandGetFull(poker, player, winning->full);
// Reset the winning status.
winning->setSize = 0;
//////////////////////// Now look for the winning set ////////////////////////
// Royal / Straight Flush
for(i = 0; i < winning->fullSize; i++) {
card = winning->full[i];
number = cardGetNumber(card);
if(number < CARD_FIVE) continue;
suit = cardGetSuit(card);
winning->setSize = 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->fullSize, cardGet(l, suit));
if(index == -1) break;
winning->set[j] = winning->full[index];
winning->setSize++;
}
// Check if has all necessary cards.
if(winning->setSize < POKER_WINNING_SET_SIZE) continue;
// Add self to array
winning->set[0] = winning->full[i];
winning->type = (
number == CARD_ACE ? POKER_WINNING_TYPE_ROYAL_FLUSH :
POKER_WINNING_TYPE_STRAIGHT_FLUSH
);
return;
}
// 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(cardContains(winning->set, winning->setSize, card) != -1) continue;
number = cardGetNumber(card);
pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs);
// 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.
// Copy found pairs.
for(j = 0; j < pairCount; j++) {
winning->set[winning->setSize + j] = winning->full[pairs[j]];
}
winning->setSize += pairCount;
// Winned?
if(winning->setSize != POKER_WINNING_SET_SIZE) continue;
winning->type = POKER_WINNING_TYPE_FULL_HOUSE;
printf("Full House\n");
return;
}
// Flush (5 same suit)
for(i = 0; i < winning->fullSize; i++) {
card = winning->full[i];
suit = cardGetSuit(card);
winning->setSize = 1;
for(j = i+1; j < winning->fullSize; j++) {
if(cardGetSuit(winning->full[j]) != suit) continue;
winning->set[winning->setSize] = winning->full[j];
winning->setSize++;
if(winning->setSize == POKER_WINNING_SET_SIZE) break;
}
if(winning->setSize < POKER_WINNING_SET_SIZE) continue;
winning->set[0] = winning->full[0];
winning->type = POKER_WINNING_TYPE_FLUSH;
return;
}
// Straight (sequence any suit)
winning->setSize = 0;
for(i = 0; i < winning->fullSize; i++) {
card = winning->full[i];
number = cardGetNumber(card);
if(number < CARD_FIVE) continue;
winning->setSize = 1;
for(j = 1; j <= 4; j++) {
l = number == CARD_FIVE && j == 4 ? CARD_ACE : number - j;//Ace low.
index = cardContainsNumber(winning->full, winning->fullSize, l);
if(index == -1) break;
winning->set[j] = winning->full[index];
winning->setSize++;
}
// Check if has all necessary cards.
if(winning->setSize < POKER_WINNING_SET_SIZE) continue;
winning->set[0] = winning->full[i];
winning->type = POKER_WINNING_TYPE_STRAIGHT;
return;
}
// Three 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 != 3) continue;
winning->setSize = pairCount;
for(j = 0; j < pairCount; j++) winning->set[j] = winning->full[pairs[j]];
winning->type = POKER_WINNING_TYPE_THREE_OF_A_KIND;
_pokerWinnerFillRemaining(winning);
return;
}
// Two Pair
winning->setSize = 0;
for(i = 0; i < winning->fullSize; i++) {
card = winning->full[i];// Check we haven't already added this card.
if(cardContains(winning->set, winning->setSize, card) != -1) {
continue;
}
number = cardGetNumber(card);
pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs);
if(pairCount != 2) continue;
for(j = 0; j < pairCount; j++) {
winning->set[j] = winning->full[winning->setSize + pairs[j]];
}
// arrayCopy(sizeof(int32_t), pairs, pairCount, winning->set+winning->setSize);
winning->setSize += pairCount;
if(winning->setSize != 4) continue;
winning->type = POKER_WINNING_TYPE_TWO_PAIR;
_pokerWinnerFillRemaining(winning);
return;
}
// Pair
if(winning->setSize == 2) {
winning->type = POKER_WINNING_TYPE_PAIR;
_pokerWinnerFillRemaining(winning);
return;
}
// High card
winning->setSize = 0;
_pokerWinnerFillRemaining(winning);
winning->type = POKER_WINNNIG_TYPE_HIGH_CARD;
return;
}
void _pokerWinnerFillRemaining(pokerplayerwinning_t *winning) {
uint8_t i, highest, current;
card_t highestCard, currentCard;
// Set the kicker
winning->kicker = 0xFF;
// Fill the remaining cards
while(winning->setSize < POKER_WINNING_SET_SIZE) {
highest = 0xFF;
for(i = 0; i < winning->fullSize; i++) {
currentCard = winning->full[i];
if(cardContains(winning->set, winning->setSize, currentCard) != -1) {
continue;
}
if(highest == 0xFF) {
highestCard = currentCard;
highest = cardGetNumber(highestCard);
} else {
current = cardGetNumber(currentCard);
if(current != CARD_ACE && current < highest) continue;
highestCard = currentCard;
highest = current;
}
}
winning->set[winning->setSize++] = highestCard;
}
cardHandSort(winning->set, winning->setSize);
}
card_t pokerWinnerCompare(pokerplayerwinning_t *left, pokerplayerwinning_t *right) {
uint8_t i, number;
card_t card;
int32_t index;
card_t highCardLeft, highCardRight;
uint8_t highNumberLeft, highNumberRight;
highNumberLeft = 0xFF;
highNumberRight = 0xFF;
for(i = 0; i < left->setSize; i++) {
card = left->set[i];
number = cardGetNumber(card);
if(highNumberLeft != 0xFF && number < highNumberLeft) continue;// Quick check
index = cardContainsNumber(right->set, right->setSize, number);
if(index != -1) continue;// In other?
if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberRight < number) {
highNumberLeft = number;
highCardLeft = card;
}
}
for(i = 0; i < right->setSize; i++) {
card = right->set[i];
number = cardGetNumber(card);
if(highNumberRight != 0xFF && number < highNumberRight) continue;
index = cardContainsNumber(left->set, left->setSize, number);
if(index != -1) continue;
if(highNumberRight == 0xFF||number == CARD_ACE||highNumberRight < number) {
highNumberRight = number;
highCardRight = card;
}
}
if(highNumberLeft < highNumberRight) return 0xFF;
return highCardLeft;//Greater or Equal to.
}
void pokerWinnerCalculate(poker_t *poker) {
uint8_t i, j, number, highNumber;
pokerwinner_t *winner;
pokerplayerwinning_t *left, *right;
pokerplayer_t *player;
card_t card, highCard;
bool isWinner;
winner = &poker->winner;
winner->winnerCount = 0;
// Get winning sets
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
left = winner->winnings + i;
left->type = POKER_WINNING_TYPE_NULL;
player = poker->players + i;
if(!pokerPlayerIsAlive(player)) continue;
// Get the players' winning state.
pokerWinnerPlayerGet(poker, player, left);
}
// Compare against each player
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
left = winner->winnings + i;
if(left->type == POKER_WINNING_TYPE_NULL) continue;
isWinner = true;
highNumber = 0xFF;
for(j = 0; j < POKER_PLAYER_COUNT; j++) {
if(i == j) continue;
right = winner->winnings + j;
if(right->type == POKER_WINNING_TYPE_NULL) continue;
// Am I the better hand / Is it the better hand?
if(left->type < right->type) continue;
if(left->type > right->type) {
isWinner = false;
break;
}
// Equal, compare hands.
card = pokerWinnerCompare(left, right);
if(card == 0xFF) {
isWinner = false;
break;
}
// Determine high card.
number = cardGetNumber(card);
if(highNumber == 0xFF || number == CARD_ACE || number > highNumber) {
highCard = card;
highNumber = number;
}
}
if(!isWinner) continue;
left->kicker = highCard;
winner->winners[winner->winnerCount++] = i;
}
}

62
src/poker/winner.h Normal file
View File

@ -0,0 +1,62 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <dawn/dawn.h>
#include "card.h"
#include "player.h"
/**
* Returns the full hand for a given player including the best cards on the
* bench.
*
* @param poker Poker game instance.
* @param player Poker player game instance.
* @param cards Array of at least 7 length to store the array.
*/
void pokerWinnerHandGetFull(poker_t *poker, pokerplayer_t *player,
card_t *cards
);
/**
* Calculates and returns the winning state for a given player
*
* @param poker Poker game instance.
* @param player Player game instance.
* @param winning Pointer to the poker winning to fill out.
* @return The winning state for this player.
*/
void pokerWinnerPlayerGet(
poker_t *poker, pokerplayer_t *player, pokerplayerwinning_t *winning
);
/**
* Fills the remaining cards for a given poker player winning hand. Essentially
* this will just take the highest cards and slot them into the array.
* @param winning Pointer to the poker winning to fill out.
*/
void _pokerWinnerFillRemaining(pokerplayerwinning_t *winning);
/**
* Compares two winning sets. The returned card is the kicker if the LEFT side
* is the winner. If LEFT is not a winner then 0xFF will be returned.
*
* @param left Left winning set.
* @param right Right winning set.
* @return The kicker card from left's hand or 0xFF if left is not the winner.
*/
card_t pokerWinnerCompare(
pokerplayerwinning_t *left, pokerplayerwinning_t *right
);
/**
* Determines the winning player for the game. Values will be stored back into
* the poker winning state.
*
* @param poker Poker game instance.
*/
void pokerWinnerCalculate(poker_t *poker);