Started merging new poker code in.

This commit is contained in:
YourWishes committed 2021-10-09 15:43:26 -07:00
1 parent aff317b904
commit 131c59fbf6
41 files changed
+1379 -1082

No files matched your search

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+39
View File
@@ -0,0 +1,39 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "poker.h"
void pokerGameWin(poker_t *poker) {
uint8_t i;
pokerplayerwinning_t *winning;
pokerplayer_t *player;
int32_t chipsRounded, chipsDifferent;
float chipsEach;
poker->state = POKER_STATE_DECIDING_WINNER;
// Get the chips each.
chipsEach = poker->bet.pot / ((float)poker->winner.winnerCount);
// Now work out the rounded offset chips.
chipsRounded = (int32_t)mathFloor(chipsEach);
chipsDifferent = poker->bet.pot - chipsRounded;
// Let's start by rewarding the winnings to the players.
for(i = 0; i < poker->winner.winnerCount; i++) {
player = poker->players + poker->winner.winners[i];
winning = poker->winner.winnings + i;
player->chips += chipsRounded;
if(i == 0) player->chips += chipsDifferent;
}
// Now kill the players who are terrible low life gamblers.
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
player = poker->players + i;
if(player->chips <= 0) player->state &= POKER_PLAYER_STATE_OUT;
}
}
+60
View File
@@ -0,0 +1,60 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "bet.h"
#include "dealer.h"
#include "winner.h"
/** How many cards to deal each player during the deal round */
#define POKER_DEAL_CARD_EACH 2
/** How many cards are dealt for the flop, turn and river */
#define POKER_FLOP_CARD_COUNT 3
#define POKER_TURN_CARD_COUNT 1
#define POKER_RIVER_CARD_COUNT 1
#define POKER_STATE_NULL 0x00
#define POKER_STATE_STARTING_MATCH 0x01
#define POKER_STATE_STARTING_ROUND 0x02
#define POKER_STATE_TAKING_BLINDS 0x03
#define POKER_STATE_DEALING 0x04
#define POKER_STATE_CARDS_FLOPPING 0x05
#define POKER_STATE_BETTING 0x06
#define POKER_STATE_DECIDING_WINNER 0x07
typedef struct {
/** Poker betting state */
pokerbet_t bet;
/** Player States */
pokerdealer_t dealer;
pokerplayer_t players[POKER_PLAYER_COUNT];
/** Winning player states */
pokerwinner_t winner;
/** The current player that is the dealer */
uint8_t roundDealer;
/** Which player is the small blind for this round */
uint8_t roundSmallBlind;
/** Which player is the big blind for this round */
uint8_t roundBigBlind;
uint8_t state;
} poker_t;
/**
* Action the poker game winning state after it has been calculated previously.
*
* @param poker Poker game to action the winning state of.
*/
void pokerGameWin(poker_t *poker);
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
-3
View File
@@ -7,9 +7,6 @@
#pragma once
#include "../../../libs.h"
#include "../../../poker/actions/flop.h"
#include "../../../poker/turn.h"
#include "../../../poker/bet.h"
#include "../pokerdiscussion.h"
#include "action.h"
#include "restack.h"
-3
View File
@@ -7,9 +7,6 @@
#pragma once
#include "../../../libs.h"
#include "../../../poker/actions/flop.h"
#include "../../../poker/turn.h"
#include "../../../poker/bet.h"
#include "../pokerdiscussion.h"
#include "action.h"
#include "restack.h"
-3
View File
@@ -11,9 +11,6 @@
#include "action.h"
#include "../pokergame.h"
#include "../../../display/animation/queue.h"
#include "../../../poker/turn.h"
#include "../../../poker/bet.h"
#include "../../../poker/actions/flop.h"
/** Callback for when the queue restack action stars. */
void _pokerGameActionRestackOnStart(
-4
View File
@@ -6,10 +6,6 @@
#pragma once
#include "../../../libs.h"
#include "action.h"
#include "../../../poker/bet.h"
#include "../../../poker/actions/round.h"
#include "../../../poker/actions/blinds.h"
#include "../../../poker/actions/deal.h"
#include "../pokerdiscussion.h"
#include "bet.h"
+1 -1
View File
@@ -18,7 +18,7 @@ void _pokerGameActionStartOnEnd(queue_t *queue,queueaction_t *action,uint8_t i){
pokergame_t *game = (pokergame_t *)action->data;
// Begin the match
pokerActionMatchAdd(&game->scene.conversation.actionQueue, &game->poker);
pokerInit(&game->poker);
// Say that.
data.poker = game;
-1
View File
@@ -9,7 +9,6 @@
#include "../../../libs.h"
#include "../../../vn/conversation/talk.h"
#include "../../../display/animation/queue.h"
#include "../../../poker/actions/match.h"
#include "../pokerdiscussion.h"
#include "round.h"
#include "action.h"
-2
View File
@@ -7,8 +7,6 @@
#pragma once
#include "../../../libs.h"
#include "../../../poker/winner.h"
#include "../../../poker/poker.h"
#include "../pokerdiscussion.h"
#include "action.h"
#include "round.h"
+7 -7
View File
@@ -20,7 +20,7 @@ void pokerDiscussionGet(
case POKER_DISCUSSION_REASON_MATCH_START:
discussion->count++;
discussion->messages[0] = "Match Start";
discussion->players[0] = POKER_DEALER_INDEX;
discussion->players[0] = POKER_WORLD_DEALER_INDEX;
discussion->emotions[0] = VN_CHARACTER_EMOTION_BORED;
break;
@@ -28,7 +28,7 @@ void pokerDiscussionGet(
case POKER_DISCUSSION_REASON_ROUND_START:
discussion->count++;
discussion->messages[0] = "Round Start";
discussion->players[0] = POKER_DEALER_INDEX;
discussion->players[0] = POKER_WORLD_DEALER_INDEX;
discussion->emotions[0] = VN_CHARACTER_EMOTION_BORED;
break;
@@ -36,7 +36,7 @@ void pokerDiscussionGet(
case POKER_DISCUSSION_REASON_BLINDS_TAKEN:
discussion->count++;
discussion->messages[0] = "Blinds\nhave been taken.";
discussion->players[0] = POKER_DEALER_INDEX;
discussion->players[0] = POKER_WORLD_DEALER_INDEX;
discussion->emotions[0] = VN_CHARACTER_EMOTION_BORED;
break;
@@ -44,7 +44,7 @@ void pokerDiscussionGet(
case POKER_DISCUSSION_REASON_DEAL:
discussion->count++;
discussion->messages[0] = "Cards dealt.";
discussion->players[0] = POKER_DEALER_INDEX;
discussion->players[0] = POKER_WORLD_DEALER_INDEX;
discussion->emotions[0] = VN_CHARACTER_EMOTION_BORED;
break;
@@ -88,14 +88,14 @@ void pokerDiscussionGet(
case POKER_DISCUSSION_REASON_FLOP:
discussion->count++;
discussion->messages[0] = "Doing the flop.";
discussion->players[0] = POKER_DEALER_INDEX;
discussion->players[0] = POKER_WORLD_DEALER_INDEX;
discussion->emotions[0] = VN_CHARACTER_EMOTION_ANIME_MOM;
break;
case POKER_DISCUSSION_REASON_BETTING_DONE:
discussion->count++;
discussion->messages[0] = "Winner Winner Chicken Dinner";
discussion->players[0] = POKER_DEALER_INDEX;
discussion->players[0] = POKER_WORLD_DEALER_INDEX;
discussion->emotions[0] = VN_CHARACTER_EMOTION_SMUG_VERY;
break;
@@ -103,7 +103,7 @@ void pokerDiscussionGet(
default:
discussion->count++;
discussion->messages[0] = "Hmm, this seems to be an error message.";
discussion->players[0] = POKER_DEALER_INDEX;
discussion->players[0] = POKER_WORLD_DEALER_INDEX;
discussion->emotions[0] = VN_CHARACTER_EMOTION_CONCERNED_WORRIED;
break;
}
-1
View File
@@ -10,7 +10,6 @@
#include "../../vn/conversation/vnconversation.h"
#include "../../vn/conversation/talk.h"
#include "actions/look.h"
#include "../../poker/turn.h"
/** Maximum number of messages that the discussion buffer can hold */
#define POKER_DISCUSSION_MESSAGE_COUNT_MAX 32
+83 -81
View File
@@ -35,7 +35,7 @@ void pokerUiInit(pokerui_t *ui) {
labelInit(&ui->label);
// Initialize the frames for each player.
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
for(i = 0; i < POKER_PLAYER_COUNT_MAX; i++) {
frameBufferInit(ui->frames + i,
POKER_UI_PLAYER_IMAGE_RESOLUTION,
POKER_UI_PLAYER_IMAGE_RESOLUTION
@@ -65,7 +65,7 @@ void pokerUiUpdate(
// Render the face of each player.
j = 0;
shaderUse(shader);
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
for(i = 0; i < POKER_PLAYER_COUNT_MAX; i++) {
player = players + j;
// Locate the XYZ position of the camera to look at the player
@@ -108,100 +108,102 @@ void pokerUiRender(
scale = fontGetScale(FONT_SIZE_DEFAULT);
// <testing>
if(poker->state >= POKER_STATE_DEALING) {
for(j = 0; j < POKER_PLAYER_COUNT; j++) {
player = poker->players + j;
for(i = 0; i < player->cardCount; i++) {
pokerUiSetImageToCard(&ui->card,&assets->cardTexture,player->cards[i]);
imageRender(&ui->card, &assets->shader, i * 64.0f, j * 100.0f);
}
}
// if(poker->state >= POKER_STATE_DEALING) {
// for(j = 0; j < POKER_PLAYER_COUNT_MAX; j++) {
// player = poker->players + j;
// for(i = 0; i < player->cardCount; i++) {
// pokerUiSetImageToCard(&ui->card,&assets->cardTexture,player->cards[i]);
// imageRender(&ui->card, &assets->shader, i * 64.0f, j * 100.0f);
// }
// }
for(j = 0; j < poker->dealer.cardsFacing; j++) {
pokerUiSetImageToCard(
&ui->card, &assets->cardTexture, poker->dealer.cards[j]
);
imageRender(&ui->card, &assets->shader, 200, j * 100.0f);
}
}
// for(j = 0; j < poker->communitySize; j++) {
// pokerUiSetImageToCard(
// &ui->card, &assets->cardTexture, poker->community[j]
// );
// imageRender(&ui->card, &assets->shader, 200, j * 100.0f);
// }
// // }
// Betting UI
if(ui->betShow) {
sprintf(message, "Press down to fold, up to raise, right to check/call.");
labelSetText(&ui->label, &assets->font, message);
labelRender(&ui->label, &assets->shader, 300, 100);
// // Betting UI
// if(ui->betShow) {
// sprintf(message, "Press down to fold, up to raise, right to check/call.");
// labelSetText(&ui->label, &assets->font, message);
// labelRender(&ui->label, &assets->shader, 300, 100);
if(inputIsPressed(&engine->input, INPUT_DOWN)) {
ui->betTurn = pokerTurnFold(poker, poker->bet.better);
ui->betTurnMade = true;
} else if(inputIsPressed(&engine->input, INPUT_RIGHT)) {
if(pokerTurnCanPlayerCheck(poker, poker->bet.better)) {
ui->betTurn = pokerTurnCheck(poker, poker->bet.better);
} else {
ui->betTurn = pokerTurnCall(poker, poker->bet.better);
}
ui->betTurnMade = true;
}
// if(inputIsPressed(&engine->input, INPUT_DOWN)) {
// ui->betTurn = pokerTurnFold(poker, poker->bet.better);
// ui->betTurnMade = true;
// } else if(inputIsPressed(&engine->input, INPUT_RIGHT)) {
// if(pokerTurnCanPlayerCheck(poker, poker->bet.better)) {
// ui->betTurn = pokerTurnCheck(poker, poker->bet.better);
// } else {
// ui->betTurn = pokerTurnCall(poker, poker->bet.better);
// }
// ui->betTurnMade = true;
// }
if(ui->betTurnMade) ui->betShow = false;
}
// if(ui->betTurnMade) ui->betShow = false;
// }
// Player UI
j = 0;
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
// Get the player.
player = poker->players + i;
// // Player UI
// j = 0;
// for(i = 0; i < POKER_PLAYER_COUNT; i++) {
// // Get the player.
// player = poker->players + i;
// Position the grid itself.
x = engine->render.width - POKER_UI_PLAYER_WIDTH;
y = (float)(POKER_UI_PLAYER_HEIGHT * j);
// // Position the grid itself.
// x = engine->render.width - POKER_UI_PLAYER_WIDTH;
// y = (float)(POKER_UI_PLAYER_HEIGHT * j);
// Render face
gridGetChild(&ui->grid, 1, 0, 1, 2, &gx, &gy, &gw, &gh);
shaderUseTexture(&assets->shader, &(ui->frames + j)->texture);
shaderUsePosition(&assets->shader, x + gx, y + gy, 0, 0,0,0);
primitiveDraw(&ui->quad, 0, -1);
// // Render face
// gridGetChild(&ui->grid, 1, 0, 1, 2, &gx, &gy, &gw, &gh);
// shaderUseTexture(&assets->shader, &(ui->frames + j)->texture);
// shaderUsePosition(&assets->shader, x + gx, y + gy, 0, 0,0,0);
// primitiveDraw(&ui->quad, 0, -1);
// Render chips
sprintf(message, "$%i", player->chips);
ui->label.maxWidth = -1;
labelSetText(&ui->label, &assets->font, message);
align = gridGetAndAlignChild(
&ui->grid, 0, 0, 1, 1,
ALIGN_POS_END|ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER|ALIGN_SIZE_ORIGINAL,
ui->label.info.width, ui->label.info.height
);
labelRender(&ui->label, &assets->shader, x+align.x, y+align.y);
// // Render chips
// sprintf(message, "$%i", player->chips);
// ui->label.maxWidth = -1;
// labelSetText(&ui->label, &assets->font, message);
// align = gridGetAndAlignChild(
// &ui->grid, 0, 0, 1, 1,
// ALIGN_POS_END|ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER|ALIGN_SIZE_ORIGINAL,
// ui->label.info.width, ui->label.info.height
// );
// labelRender(&ui->label, &assets->shader, x+align.x, y+align.y);
// Render state
if(player->state & POKER_PLAYER_STATE_OUT) {
sprintf(message, "Out");
} else if(player->state & POKER_PLAYER_STATE_FOLDED) {
sprintf(message, "Folded");
} else if(player->state & POKER_PLAYER_STATE_SHOWING) {
sprintf(message, "Showing");
} else if(poker->bet.better == j) {
sprintf(message, "Thinking");
} else {
sprintf(message, "Whatever");
}
labelSetText(&ui->label, &assets->font, message);
align = gridGetAndAlignChild(
&ui->grid, 0, 1, 1, 1,
ALIGN_POS_END | ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER | ALIGN_SIZE_ORIGINAL,
ui->label.info.width, ui->label.info.height
);
labelRender(&ui->label, &assets->shader, x+align.x, y+align.y);
// // Render state
// if(player->state & POKER_PLAYER_STATE_OUT) {
// sprintf(message, "Out");
// } else if(player->state & POKER_PLAYER_STATE_FOLDED) {
// sprintf(message, "Folded");
// } else if(player->state & POKER_PLAYER_STATE_SHOWING) {
// sprintf(message, "Showing");
// } else if(poker->bet.better == j) {
// sprintf(message, "Thinking");
// } else {
// sprintf(message, "Whatever");
// }
// labelSetText(&ui->label, &assets->font, message);
// align = gridGetAndAlignChild(
// &ui->grid, 0, 1, 1, 1,
// ALIGN_POS_END | ALIGN_SIZE_ORIGINAL, ALIGN_POS_CENTER | ALIGN_SIZE_ORIGINAL,
// ui->label.info.width, ui->label.info.height
// );
// labelRender(&ui->label, &assets->shader, x+align.x, y+align.y);
// Increment.
j++;
}
// // Increment.
// j++;
// }
}
void pokerUiDispose(pokerui_t *ui) {
uint8_t i;
for(i = 0; i < POKER_PLAYER_COUNT; i++) frameBufferDispose(ui->frames + i);
for(i = 0; i < POKER_PLAYER_COUNT_MAX; i++) {
frameBufferDispose(ui->frames + i);
}
labelDispose(&ui->label);
primitiveDispose(&ui->quad);
imageDispose(&ui->card);
+2 -5
View File
@@ -20,11 +20,8 @@
#include "../../vn/vncharacter.h"
#include "../../ui/grid.h"
#include "../../ui/align.h"
#include "../../poker/player.h"
#include "../../poker/poker.h"
#include "../../poker/bet.h"
#include "../../poker/turn.h"
#include "../../vn/vnscene.h"
#include "../../poker/poker.h"
#include "pokerworld.h"
#include "pokergameassets.h"
@@ -47,7 +44,7 @@ typedef struct {
label_t label;
grid_t grid;
image_t card;
framebuffer_t frames[POKER_PLAYER_COUNT];
framebuffer_t frames[POKER_PLAYER_COUNT_MAX];
/** Betting UI */
bool betShow;
+1 -1
View File
@@ -22,7 +22,7 @@ void pokerWorldInit(
skywallInit(&world->skywall);
// Initialize the players
for(i = 0x00; i < POKER_PLAYER_COUNT; i++) {
for(i = 0x00; i < POKER_PLAYER_COUNT_MAX; i++) {
character = scene->characters + scene->characterCount;
vnCharacterInit(character, &assets->pennyTexture,
POKER_WORLD_PENNY_BASE_WIDTH, POKER_WORLD_PENNY_BASE_HEIGHT,
+6 -5
View File
@@ -13,9 +13,8 @@
#include "../../display/primitives/skywall.h"
#include "../../vn/vnscene.h"
#include "../../vn/vncharacter.h"
#include "../../poker/player.h"
#include "../../poker/dealer.h"
#include "../../engine/engine.h"
#include "../../poker/poker.h"
#include "pokergameassets.h"
/** How far away from the camera are the characters distanced */
@@ -39,14 +38,16 @@
#define POKER_WORLD_SEAT_COUNT 8
/** The seat index for a given player index */
#define POKER_WORLD_SEAT_FOR_PLAYER(p) (p - (POKER_PLAYER_COUNT/2))
#define POKER_WORLD_SEAT_FOR_PLAYER(p) (p - (POKER_PLAYER_COUNT_MAX/2))
/** The seat that the dealer occupies */
#define POKER_WORLD_SEAT_DEALER POKER_WORLD_SEAT_FOR_PLAYER(POKER_DEALER_INDEX)
#define POKER_WORLD_SEAT_DEALER POKER_WORLD_SEAT_FOR_PLAYER(\
POKER_WORLD_DEALER_INDEX\
)
/** The seat index for a given character index */
#define pokerWorldSeatFromIndex(i) (\
i == POKER_DEALER_INDEX ? \
i == POKER_WORLD_DEALER_INDEX ? \
POKER_WORLD_SEAT_DEALER : \
POKER_WORLD_SEAT_FOR_PLAYER(i) \
)
+618 -23
View File
@@ -7,33 +7,628 @@
#include "poker.h"
void pokerGameWin(poker_t *poker) {
void pokerInit(poker_t *poker) {
poker->playerCount = 0;
poker->playerDealer = 0;
poker->playerSmallBlind = 0;
poker->playerBigBlind = 0;
pokerResetRound(poker);
}
void pokerResetRound(poker_t *poker) {
uint8_t i;
pokerplayerwinning_t *winning;
pokerplayer_t *player;
int32_t chipsRounded, chipsDifferent;
float chipsEach;
poker->state = POKER_STATE_DECIDING_WINNER;
poker->deckSize = cardWriteDeck(poker->deck);
poker->graveSize = 0;
poker->communitySize = 0;
poker->potCount = 0;
pokerPotAdd(poker);
// Get the chips each.
chipsEach = poker->bet.pot / ((float)poker->winner.winnerCount);
// Now work out the rounded offset chips.
chipsRounded = (int32_t)mathFloor(chipsEach);
chipsDifferent = poker->bet.pot - chipsRounded;
// Let's start by rewarding the winnings to the players.
for(i = 0; i < poker->winner.winnerCount; i++) {
player = poker->players + poker->winner.winners[i];
winning = poker->winner.winnings + i;
player->chips += chipsRounded;
if(i == 0) player->chips += chipsDifferent;
}
// Now kill the players who are terrible low life gamblers.
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
for(i = 0; i < poker->playerCount; i++) {
player = poker->players + i;
if(player->chips <= 0) player->state &= POKER_PLAYER_STATE_OUT;
player->cardCount = 0;
player->currentBet = 0;
player->state &= ~(
POKER_PLAYER_STATE_FOLDED |
POKER_PLAYER_STATE_HAS_BET_THIS_ROUND |
POKER_PLAYER_STATE_SHOWING
);
}
}
void pokerNewDealer(poker_t *poker) {
uint8_t i, j, k;
pokerplayer_t *player;
bool foundDealer;
bool foundSmall;
foundDealer = false;
foundSmall = false;
j = poker->playerDealer + 1;
for(i = 0; i < poker->playerCount; i++) {
k = (j + i) % poker->playerCount;
player = poker->players + k;
if(player->state & POKER_PLAYER_STATE_OUT) continue;
if(!foundDealer) {
poker->playerDealer = k;
foundDealer = true;
} else if(!foundSmall) {
poker->playerSmallBlind = k;
foundSmall = true;
} else {
poker->playerBigBlind = k;
break;
}
}
}
void pokerTakeBlinds(poker_t *poker, int32_t small, int32_t big) {
pokerPlayerBet(poker, poker->playerSmallBlind, small);
pokerPlayerBet(poker, poker->playerBigBlind, big);
}
int32_t pokerGetCallValue(poker_t *poker) {
uint8_t i;
int32_t call;
call = 0;
for(i = 0; i < poker->playerCount; i++) {
call = mathMax(call, poker->players[i].currentBet);
}
return call;
}
// Pot functions
uint8_t pokerPotAdd(poker_t *poker) {
pokerpot_t *pot;
uint8_t i = poker->potCount++;
pot = poker->pots + i;
pot->chips = 0;
pot->playerCount = 0;
return i;
}
void pokerPotAddPlayer(pokerpot_t *pot, uint8_t playerIndex) {
if(arrayContains(
sizeof(uint8_t), pot->players, pot->playerCount, &playerIndex
)) return;
pot->players[pot->playerCount++] = playerIndex;
}
// Dealer Functions
void pokerTurn(poker_t *poker, uint8_t count) {
uint8_t i;
for(i = 0; i < count; i++) {
cardDeal(
poker->deck, &poker->deckSize, poker->community, &poker->communitySize
);
}
}
void pokerBurn(poker_t *poker, uint8_t count) {
uint8_t i;
for(i = 0; i < count; i++) {
cardDeal(poker->deck, &poker->deckSize, poker->grave, &poker->graveSize);
}
}
// Player Functions
uint8_t pokerPlayerAdd(poker_t *poker) {
pokerplayer_t *player;
uint8_t i = poker->playerCount++;
player = poker->players + i;
player->cardCount = 0;
player->chips = 0;
player->currentBet = 0;
player->state = POKER_PLAYER_STATE_OUT;
return i;
}
void pokerPlayerDeal(poker_t *poker, pokerplayer_t *player, uint8_t count) {
uint8_t i;
for(i = 0; i < count; i++) {
cardDeal(poker->deck, &poker->deckSize, player->cards, &player->cardCount);
}
}
void pokerPlayerChipsAdd(pokerplayer_t *player, int32_t chips) {
player->chips += chips;
if(player->chips > 0) {
player->state = flagOff(player->state, POKER_PLAYER_STATE_OUT);
}
}
void pokerPlayerDealAll(poker_t *poker, uint8_t count) {
uint8_t i, j;
pokerplayer_t *player;
for(j = 0; j < count; j++) {
for(i = 0; i < poker->playerCount; i++) {
player = poker->players + i;
// Can't deal to a player who is folded or out
if(player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT)) {
continue;
}
pokerPlayerDeal(poker, player, 1);
}
}
}
bool pokerPlayerDoesNeedToBetThisRound(poker_t *poker, uint8_t playerIndex) {
pokerplayer_t *player;
player = poker->players + playerIndex;
if(player->state & POKER_PLAYER_STATE_FOLDED) return false;
if(!(player->state & POKER_PLAYER_STATE_HAS_BET_THIS_ROUND)) return true;
if(player->currentBet < pokerGetCallValue(poker)) return true;
return false;
}
uint8_t pokerPlayerGetRemainingBetter(poker_t *poker) {
uint8_t i, j;
for(i = 0; i < poker->playerCount; i++) {
j = (i + poker->playerBigBlind + 1) % poker->playerCount;
if(pokerPlayerDoesNeedToBetThisRound(poker, j)) return j;
}
return 0xFF;
}
uint8_t pokerPlayerGetNextBetter(poker_t *poker, uint8_t current) {
uint8_t i, j;
for(i = 0; i < poker->playerCount; i++) {
j = (i + current + 1) % poker->playerCount;
if(pokerPlayerDoesNeedToBetThisRound(poker, j)) return j;
}
return 0xFF;
}
int32_t pokerPlayerGetCallBet(poker_t *poker, pokerplayer_t *player) {
return pokerGetCallValue(poker) - player->currentBet;
}
// Betting
void pokerPlayerBetPot(
poker_t *poker, pokerpot_t *pot, uint8_t playerIndex, int32_t chips
) {
pokerplayer_t *player;
player = poker->players + playerIndex;
player->chips -= chips;
player->currentBet += chips;
pot->chips += chips;
player->state |= POKER_PLAYER_STATE_HAS_BET_THIS_ROUND;
pokerPotAddPlayer(pot, playerIndex);
}
void pokerPlayerBet(poker_t *poker, uint8_t playerIndex, int32_t chips) {
pokerPlayerBetPot(
poker, poker->pots + (poker->potCount - 1), playerIndex, chips
);
}
bool pokerPlayerCanCheck(poker_t *poker, pokerplayer_t *player) {
return pokerGetCallValue(poker) <= player->currentBet;
}
pokerturn_t pokerTurnFold(poker_t *poker, uint8_t player) {
return (pokerturn_t){
.chips = 0,
.confidence = 1,
.type = POKER_TURN_TYPE_FOLD
};
}
pokerturn_t pokerTurnBet(poker_t *poker, uint8_t playerIndex, int32_t chips) {
pokerturn_t turn;
pokerplayer_t *player;
int32_t i;
player = poker->players + playerIndex;
turn.confidence = 1;
if(chips == 0) {
turn.type = POKER_TURN_TYPE_CHECK;
turn.chips = 0;
} else if(player->chips <= chips) {
turn.chips = player->chips;
turn.type = POKER_TURN_TYPE_ALL_IN;
} else {
turn.chips = chips;
turn.type = POKER_TURN_TYPE_BET;
i = pokerGetCallValue(poker);
if(chips == (i - player->currentBet)) {
turn.type = POKER_TURN_TYPE_CALL;
}
}
return turn;
}
// Winning
void pokerHandGetFull(
poker_t *poker, pokerplayer_t *player, card_t cards[POKER_WINNING_FULL_SIZE]
) {
uint8_t i;
// Add the dealer hand
for(i = 0; i < poker->communitySize; i++) {
cards[i] = poker->community[i];
}
// Add the player hand
for(i = 0; i < player->cardCount; i++) {
cards[i+poker->communitySize] = player->cards[i];
}
}
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;
}
}
if(highest == 0xFF) break;
winning->set[winning->setSize++] = highestCard;
}
cardHandSort(winning->set, winning->setSize);
}
void pokerWinnerGetForPlayer(
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->communitySize + player->cardCount;
pokerHandGetFull(poker, player, winning->full);
cardHandSort(winning->full, winning->fullSize);
// 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
);
pokerWinnerFillRemaining(winning);
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;
pokerWinnerFillRemaining(winning);
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];
if(winning->setSize == POKER_WINNING_SET_SIZE) break;
}
if(winning->setSize < POKER_WINNING_SET_SIZE) continue;
winning->set[0] = winning->full[i];
winning->type = POKER_WINNING_TYPE_FLUSH;
pokerWinnerFillRemaining(winning);
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;
pokerWinnerFillRemaining(winning);
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[winning->setSize+j] = winning->full[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_WINNING_TYPE_HIGH_CARD;
return;
}
card_t pokerWinnerCompare(pokerplayerwinning_t *left, pokerplayerwinning_t *right) {
uint8_t i, number;
card_t card;
int32_t index;
uint8_t countCardsSame;
card_t highCardLeft, highCardRight;
uint8_t highNumberLeft, highNumberRight;
highNumberLeft = 0xFF;
highNumberRight = 0xFF;
countCardsSame = 0;
for(i = 0; i < left->setSize; i++) {
card = left->set[i];
number = cardGetNumber(card);
if(highNumberLeft != 0xFF && number < highNumberLeft) continue;// Quick check
// Check if this number is within the other hand or not
index = cardContainsNumber(right->set, right->setSize, number);
if(index != -1) {
// This number IS within the other hand, let's check that the EXACT card
// is a match/isn't a match.
index = cardContains(right->set, right->setSize, card);
// Exact card match
if(index != -1) {
countCardsSame++;
continue;
}
// Not exact card match.. ?
}
if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberLeft < 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) {
index = cardContains(left->set, left->setSize, card);
if(index != -1) continue;
}
if(highNumberRight == 0xFF||number == CARD_ACE||highNumberRight < number) {
highNumberRight = number;
highCardRight = card;
}
}
if(countCardsSame == left->setSize) {
for(i = 0; i < left->setSize; i++) {
card = left->set[i];
number = cardGetNumber(card);
if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberLeft < number) {
highNumberLeft = number;
highCardLeft = card;
}
}
return highCardLeft;
}
if(highCardLeft == 0xFF) return 0xFF;
if(highNumberLeft < highNumberRight) return 0xFF;
return highCardLeft;//Greater or Equal to.
}
void pokerWinnerDetermineForPot(
poker_t *poker,
pokerpot_t *pot,
pokerplayerwinning_t winners[POKER_PLAYER_COUNT_MAX],
uint8_t winnerPlayers[POKER_PLAYER_COUNT_MAX],
uint8_t *winnerCount,
uint8_t participants[POKER_PLAYER_COUNT_MAX],
uint8_t *participantCount
) {
uint8_t i, j, countPlayers, countWinners, number, highNumber;
pokerplayerwinning_t *left, *right;
pokerplayer_t *player;
card_t card, highCard;
bool isWinner;
countPlayers = 0;
countWinners = 0;
highCard = 0xFF;
// Get participating players and their hands.
for(i = 0; i < pot->playerCount; i++) {
player = poker->players + pot->players[i];
if(player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT)) {
continue;
}
participants[countPlayers] = pot->players[i];
pokerWinnerGetForPlayer(poker, player, winners + countPlayers++);
}
// Compare participating players
for(i = 0; i < countPlayers; i++) {
left = winners + i;
isWinner = true;
highNumber = 0xFF;
for(j = 0; j < countPlayers; j++) {
if(i == j) continue;
right = winners + j;
// 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;
winnerPlayers[countWinners++] = participants[i];
}
*participantCount = countPlayers;
*winnerCount = countWinners;
}
+414 -37
View File
@@ -7,54 +7,431 @@
#pragma once
#include "../libs.h"
#include "bet.h"
#include "dealer.h"
#include "winner.h"
#include "../util/flags.h"
#include "../util/array.h"
#include "../util/math.h"
#include "card.h"
/** How many cards to deal each player during the deal round */
#define POKER_DEAL_CARD_EACH 2
/** How many cards are dealt for the flop, turn and river */
#define POKER_FLOP_CARD_COUNT 3
#define POKER_TURN_CARD_COUNT 1
#define POKER_RIVER_CARD_COUNT 1
#define POKER_STATE_NULL 0x00
#define POKER_STATE_STARTING_MATCH 0x01
#define POKER_STATE_STARTING_ROUND 0x02
#define POKER_STATE_TAKING_BLINDS 0x03
#define POKER_STATE_DEALING 0x04
#define POKER_STATE_CARDS_FLOPPING 0x05
#define POKER_STATE_BETTING 0x06
#define POKER_STATE_DECIDING_WINNER 0x07
typedef struct {
/** Poker betting state */
pokerbet_t bet;
/** Maximum number of players that the game state can support */
#define POKER_PLAYER_COUNT_MAX 5
/** Maximum cards a players' hand can hold */
#define POKER_PLAYER_HAND_SIZE_MAX 2
/** Player States */
pokerdealer_t dealer;
pokerplayer_t players[POKER_PLAYER_COUNT];
#define POKER_PLAYER_STATE_FOLDED flagDefine(0)
#define POKER_PLAYER_STATE_OUT flagDefine(1)
#define POKER_PLAYER_STATE_HAS_BET_THIS_ROUND flagDefine(2)
#define POKER_PLAYER_STATE_SHOWING flagDefine(3)
/** Winning player states */
pokerwinner_t winner;
/** Maximum number of cards that the grave can hold */
#define POKER_GRAVE_SIZE_MAX CARD_DECK_SIZE
/** The current player that is the dealer */
uint8_t roundDealer;
/** Maximum number of community cards */
#define POKER_COMMUNITY_SIZE_MAX 5
/** Which player is the small blind for this round */
uint8_t roundSmallBlind;
/** Maximum number of pots in the poker game. */
#define POKER_POT_COUNT_MAX POKER_PLAYER_COUNT_MAX
/** Which player is the big blind for this round */
uint8_t roundBigBlind;
/** Maximum number of cards a winning state can hold. */
#define POKER_WINNING_FULL_SIZE (\
POKER_PLAYER_HAND_SIZE_MAX + POKER_COMMUNITY_SIZE_MAX\
)
/** How many cards in the 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_WINNING_TYPE_HIGH_CARD 0x0A
#define POKER_WINNING_CONFIDENCE_ROYAL_FLUSH 1.0f
#define POKER_WINNING_CONFIDENCE_STRAIGHT_FLUSH 0.99f
#define POKER_WINNING_CONFIDENCE_FOUR_OF_A_KIND 0.9f
#define POKER_WINNING_CONFIDENCE_FULL_HOUSE 0.85f
#define POKER_WINNING_CONFIDENCE_FLUSH 0.8f
#define POKER_WINNING_CONFIDENCE_STRAIGHT 0.7f
#define POKER_WINNING_CONFIDENCE_THREE_OF_A_KIND 0.5f
#define POKER_WINNING_CONFIDENCE_TWO_PAIR 0.4f
#define POKER_WINNING_CONFIDENCE_PAIR 0.2f
#define POKER_WINNING_CONFIDENCE_HIGH_CARD 0.1f
#define POKER_WORLD_DEALER_INDEX 0x02
#define POKER_WORLD_HUMAN_INDEX 0x02
/** Turn Types */
#define POKER_TURN_TYPE_OUT 0x00
#define POKER_TURN_TYPE_FOLD 0x01
#define POKER_TURN_TYPE_BET 0x02
#define POKER_TURN_TYPE_CALL 0x03
#define POKER_TURN_TYPE_ALL_IN 0x04
#define POKER_TURN_TYPE_CALL_ALL_IN 0x04
#define POKER_TURN_TYPE_CHECK 0x05
/** How many chips each player has by defautl */
#define POKER_BET_PLAYER_CHIPS_DEFAULT 1200
/** 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 {
/** Count of chips the player has */
int32_t chips;
/** Cards in the players' hand */
card_t cards[POKER_PLAYER_HAND_SIZE_MAX];
uint8_t cardCount;
/** Players current state */
uint8_t state;
/** Current bet that the player has done. */
int32_t currentBet;
} pokerplayer_t;
/** 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 {
/** Current pot of chips */
int32_t chips;
/** Players who are participating in the pot */
uint8_t players[POKER_PLAYER_COUNT_MAX];
uint8_t playerCount;
} pokerpot_t;
typedef struct {
/** What type of action the turn is */
uint8_t type;
/** How many chips they did in their turn (if applicable) */
int32_t chips;
/** How confident the AI is about their turn. 0 = none, 1 = full */
float confidence;
} pokerturn_t;
typedef struct {
/** Current Card Deck (Dealer) */
card_t deck[CARD_DECK_SIZE];
uint8_t deckSize;
/** Card grave (where spent cards go when burned */
card_t grave[POKER_GRAVE_SIZE_MAX];
uint8_t graveSize;
/** Dealer Hand */
card_t community[POKER_COMMUNITY_SIZE_MAX];
uint8_t communitySize;
/** List of pots in the game (side pots) */
pokerpot_t pots[POKER_POT_COUNT_MAX];
uint8_t potCount;
/** Players within the game */
pokerplayer_t players[POKER_PLAYER_COUNT_MAX];
uint8_t playerCount;
/** Index of the dealer player */
uint8_t playerDealer;
/** Index of the small blind player */
uint8_t playerSmallBlind;
/** Index of the big blind player */
uint8_t playerBigBlind;
} poker_t;
/**
* Action the poker game winning state after it has been calculated previously.
* Initialize the poker game instance.
*
* @param poker Poker game to action the winning state of.
* @param poker Poker game instance.
*/
void pokerGameWin(poker_t *poker);
void pokerInit(poker_t *poker);
/**
* Reset the poker game instance for the new round.
*
* @param poker Poker game instance.
*/
void pokerResetRound(poker_t *poker);
/**
* Cycles to the next dealer. This will also select the new small and big blind
* players.
*
* @param poker Poker game to select a new dealer for.
*/
void pokerNewDealer(poker_t *poker);
/**
* Take the blinds from the blind players.
*
* @param poker Poker game instance.
* @param small Small blind amount.
* @param big Big blind amount.
*/
void pokerTakeBlinds(poker_t *poker, int32_t small, int32_t big);
/**
* Gets the amount of chips necessary to call the current bet.
*
* @param poker Poker game instance.
* @return Chips necessary to call the current bet.
*/
int32_t pokerGetCallValue(poker_t *poker);
/**
* Adds a new pot to the poker game instance.
*
* @param poker Poker game instance to add a pot to.
* @return The index of the pot within the array of pots.
*/
uint8_t pokerPotAdd(poker_t *poker);
/**
* Add a player to a pot. This will not let you add the same player to the pot
* twice.
*
* @param pot Pot to add to.
* @param playerIndex Players' index to add to the pot.
*/
void pokerPotAddPlayer(pokerpot_t *pot, uint8_t playerIndex);
/**
* Turns over cards from the deck onto the table (from the deck into the dealer
* hand)
*
* @param poker Poker game instance.
* @param count Count of cards to deal.
*/
void pokerTurn(poker_t *poker, uint8_t count);
/**
* Burns a set of cards off the top of the deck into the graveyard.
*
* @param poker Poker game instance.
* @param count Count of cards to burn.
*/
void pokerBurn(poker_t *poker, uint8_t count);
/**
* Add a player to the game. The player starts in an out state (with no chips).
*
* @param poker Poker game instance to add to.
* @return Player index.
*/
uint8_t pokerPlayerAdd(poker_t *poker);
/**
* Deal a card to a player.
*
* @param poker Poker game instance.
* @param player Poker player to deal to.
* @param count Count of cards to deal to the player.
*/
void pokerPlayerDeal(poker_t *poker, pokerplayer_t *player, uint8_t count);
/**
* Add chips to a player. This will also update their state if they were out
* to ensure that they are no longer.
*
* @param player Player to add chips to.
* @param chips Amount of chips to add.
*/
void pokerPlayerChipsAdd(pokerplayer_t *player, int32_t chips);
/**
* Deal card(s) to every active player.
*
* @param poker Poker game instance.
* @param count Count of cards to deal.
*/
void pokerPlayerDealAll(poker_t *poker, uint8_t count);
/**
* Checks a players' state and decided whether or not the players still needs to
* bet for the current round. This will check both whether the player has bet in
* the current round yet, and whether or not they have met the call value of the
* active pot.
*
* @param poker Poker game instance.
* @param playerIndex Player index to check.
* @return
*/
bool pokerPlayerDoesNeedToBetThisRound(poker_t *poker, uint8_t playerIndex);
/**
* Returns the index of the first player that remains to bet for the current
* round.
*
* @param poker Poker game instance.
* @return The player index of the remaining player, otherwise 0xFF.
*/
uint8_t pokerPlayerGetRemainingBetter(poker_t *poker);
/**
* Returns the index of the first player that remains to bet for the current
* round. This is based on whatever current better player index you provide.
*
* @param poker Poker game instance.
* @param current Current better player index.
* @return The player index of the next remaining player, otherwise 0xFF.
*/
uint8_t pokerPlayerGetNextBetter(poker_t *poker, uint8_t current);
/**
* Get the bet necessary for a specific player to make a call. This takes the
* players current bet and the bet necessary to call into the pot and will
* return the difference.
*
* @param poker Poker game instance.
* @param player Player instance to get the call value for.
* @return The count of chips needed to call into the current active pot.
*/
int32_t pokerPlayerGetCallBet(poker_t *poker, pokerplayer_t *player);
/**
* Let a player bet chips into the pot.
*
* @param poker Poker game instance.
* @param pot Poker pot to bet in to.
* @param playerIndex The players' index that is betting.
* @param chips The amount of chips the player is betting.
*/
void pokerPlayerBetPot(
poker_t *poker, pokerpot_t *pot, uint8_t playerIndex, int32_t chips
);
/**
* Let a player bet chips into the current pot.
*
* @param bet Poker game instance.
* @param playerIndex The players' index that is betting.
* @param chips The amount of chips the player is betting.
*/
void pokerPlayerBet(poker_t *poker, uint8_t playerIndex, int32_t chips);
/**
* Determine whether or not a player CAN check, given the current max bet and
* the players current bet.
*
* @param poker Poker game instance.
* @param player Player to check.
* @return True if the player can check, false if they need to call first.
*/
bool pokerPlayerCanCheck(poker_t *poker, pokerplayer_t *player);
/**
* Return a turn action for the given player to fold.
*
* @param poker Poker game instance.
* @param player Player index.
* @return A turn for a fold action.
*/
pokerturn_t pokerTurnFold(poker_t *poker, uint8_t player);
/**
* Perform a turn action for betting as a player.
*
* @param poker Poker game instance.
* @param playerIndex Player index who is betting.
* @param chips Chips to raise by.
* @return A turn for a bet action.
*/
pokerturn_t pokerTurnBet(poker_t *poker, uint8_t playerIndex, int32_t chips);
/**
* Returns the full hand for a given player including the best cards on the
* bench.
*
* @param poker Poker game instance.
* @param player Poker player to get the hand for.
* @param cards Array to store the cards.
*/
void pokerHandGetFull(
poker_t *poker, pokerplayer_t *player, card_t cards[POKER_WINNING_FULL_SIZE]
);
/**
* 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. This also
* sorts the cards.
*
* @param winning Pointer to the poker winning to fill out.
*/
void pokerWinnerFillRemaining(pokerplayerwinning_t *winning);
/**
* Calculates and returns the winning state for a given player
*
* @param poker Poker game instance.
* @param player Player to get the state for.
* @param winning Output winning state struct to push data in to.
*/
void pokerWinnerGetForPlayer(
poker_t *poker, pokerplayer_t *player, 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 given pot. The pot has participating
* players, and from those participating players some will be winners. The
* participants are only the players within the pot who haven't folded or out.
*
* @param poker Poker game instance.
* @param pot Pot to get the winners for.
* @param winners Array to store the winner state in.
* @param winnerPlayers Array to store player indexes of each of the winners.
* @param winnerCount Pointer to store the count of winners in.
* @param participants Array to store player indexes of players who participate.
* @param participantCount Pointer to store the count of participants in.
*/
void pokerWinnerDetermineForPot(
poker_t *poker,
pokerpot_t *pot,
pokerplayerwinning_t winners[POKER_PLAYER_COUNT_MAX],
uint8_t winnerPlayers[POKER_PLAYER_COUNT_MAX],
uint8_t *winnerCount,
uint8_t participants[POKER_PLAYER_COUNT_MAX],
uint8_t *participantCount
);
-633
View File
@@ -1,633 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "poker.h"
void pokerInit(poker2_t *poker) {
poker->playerCount = 0;
poker->playerDealer = 0;
poker->playerSmallBlind = 0;
poker->playerBigBlind = 0;
pokerResetRound(poker);
}
void pokerResetRound(poker2_t *poker) {
uint8_t i;
poker2player_t *player;
poker->deckSize = cardWriteDeck(poker->deck);
poker->graveSize = 0;
poker->communitySize = 0;
poker->potCount = 0;
pokerPotAdd(poker);
for(i = 0; i < poker->playerCount; i++) {
player = poker->players + i;
player->cardCount = 0;
player->currentBet = 0;
player->state &= ~(
POKER_PLAYER_STATE_FOLDED |
POKER_PLAYER_STATE_HAS_BET_THIS_ROUND
);
}
}
void pokerNewDealer(poker2_t *poker) {
uint8_t i, j, k;
poker2player_t *player;
bool foundDealer;
bool foundSmall;
foundDealer = false;
foundSmall = false;
j = poker->playerDealer + 1;
for(i = 0; i < poker->playerCount; i++) {
k = (j + i) % poker->playerCount;
player = poker->players + k;
if(player->state & POKER_PLAYER_STATE_OUT) continue;
if(!foundDealer) {
poker->playerDealer = k;
foundDealer = true;
} else if(!foundSmall) {
poker->playerSmallBlind = k;
foundSmall = true;
} else {
poker->playerBigBlind = k;
break;
}
}
}
void pokerTakeBlinds(poker2_t *poker, int32_t small, int32_t big) {
pokerPlayerBet(poker, poker->playerSmallBlind, small);
pokerPlayerBet(poker, poker->playerBigBlind, big);
}
int32_t pokerGetCallValue(poker2_t *poker) {
uint8_t i;
int32_t call;
call = 0;
for(i = 0; i < poker->playerCount; i++) {
call = mathMax(call, poker->players[i].currentBet);
}
return call;
}
// Pot functions
uint8_t pokerPotAdd(poker2_t *poker) {
poker2pot_t *pot;
uint8_t i = poker->potCount++;
pot = poker->pots + i;
pot->chips = 0;
pot->playerCount = 0;
return i;
}
void pokerPotAddPlayer(poker2pot_t *pot, uint8_t playerIndex) {
if(arrayContains(
sizeof(uint8_t), pot->players, pot->playerCount, &playerIndex
)) return;
pot->players[pot->playerCount++] = playerIndex;
}
// Dealer Functions
void pokerTurn(poker2_t *poker, uint8_t count) {
uint8_t i;
for(i = 0; i < count; i++) {
cardDeal(
poker->deck, &poker->deckSize, poker->community, &poker->communitySize
);
}
}
void pokerBurn(poker2_t *poker, uint8_t count) {
uint8_t i;
for(i = 0; i < count; i++) {
cardDeal(poker->deck, &poker->deckSize, poker->grave, &poker->graveSize);
}
}
// Player Functions
uint8_t pokerPlayerAdd(poker2_t *poker) {
poker2player_t *player;
uint8_t i = poker->playerCount++;
player = poker->players + i;
player->cardCount = 0;
player->chips = 0;
player->currentBet = 0;
player->state = POKER_PLAYER_STATE_OUT;
return i;
}
void pokerPlayerDeal(poker2_t *poker, poker2player_t *player, uint8_t count) {
uint8_t i;
for(i = 0; i < count; i++) {
cardDeal(poker->deck, &poker->deckSize, player->cards, &player->cardCount);
}
}
void pokerPlayerChipsAdd(poker2player_t *player, int32_t chips) {
player->chips += chips;
if(player->chips > 0) {
player->state = flagOff(player->state, POKER_PLAYER_STATE_OUT);
}
}
void pokerPlayerDealAll(poker2_t *poker, uint8_t count) {
uint8_t i, j;
poker2player_t *player;
for(j = 0; j < count; j++) {
for(i = 0; i < poker->playerCount; i++) {
player = poker->players + i;
// Can't deal to a player who is folded or out
if(player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT)) {
continue;
}
pokerPlayerDeal(poker, player, 1);
}
}
}
bool pokerPlayerDoesNeedToBetThisRound(poker2_t *poker, uint8_t playerIndex) {
poker2player_t *player;
player = poker->players + playerIndex;
if(player->state & POKER_PLAYER_STATE_FOLDED) return false;
if(!(player->state & POKER_PLAYER_STATE_HAS_BET_THIS_ROUND)) return true;
if(player->currentBet < pokerGetCallValue(poker)) return true;
return false;
}
uint8_t pokerPlayerGetRemainingBetter(poker2_t *poker) {
uint8_t i, j;
for(i = 0; i < poker->playerCount; i++) {
j = (i + poker->playerBigBlind + 1) % poker->playerCount;
if(pokerPlayerDoesNeedToBetThisRound(poker, j)) return j;
}
return 0xFF;
}
uint8_t pokerPlayerGetNextBetter(poker2_t *poker, uint8_t current) {
uint8_t i, j;
for(i = 0; i < poker->playerCount; i++) {
j = (i + current + 1) % poker->playerCount;
if(pokerPlayerDoesNeedToBetThisRound(poker, j)) return j;
}
return 0xFF;
}
int32_t pokerPlayerGetCallBet(poker2_t *poker, poker2player_t *player) {
return pokerGetCallValue(poker) - player->currentBet;
}
// Betting
void pokerPlayerBetPot(
poker2_t *poker, poker2pot_t *pot, uint8_t playerIndex, int32_t chips
) {
poker2player_t *player;
player = poker->players + playerIndex;
player->chips -= chips;
player->currentBet += chips;
pot->chips += chips;
player->state |= POKER_PLAYER_STATE_HAS_BET_THIS_ROUND;
pokerPotAddPlayer(pot, playerIndex);
}
void pokerPlayerBet(poker2_t *poker, uint8_t playerIndex, int32_t chips) {
pokerPlayerBetPot(
poker, poker->pots + (poker->potCount - 1), playerIndex, chips
);
}
bool pokerPlayerCanCheck(poker2_t *poker, poker2player_t *player) {
return pokerGetCallValue(poker) <= player->currentBet;
}
poker2turn_t pokerTurnFold(poker2_t *poker, uint8_t player) {
return (poker2turn_t){
.chips = 0,
.confidence = 1,
.type = POKER_TURN_TYPE_FOLD
};
}
poker2turn_t pokerTurnBet(poker2_t *poker, uint8_t playerIndex, int32_t chips) {
poker2turn_t turn;
poker2player_t *player;
int32_t i;
player = poker->players + playerIndex;
turn.confidence = 1;
if(chips == 0) {
turn.type = POKER_TURN_TYPE_CHECK;
turn.chips = 0;
} else if(player->chips <= chips) {
turn.chips = player->chips;
turn.type = POKER_TURN_TYPE_ALL_IN;
} else {
turn.chips = chips;
turn.type = POKER_TURN_TYPE_BET;
i = pokerGetCallValue(poker);
if(chips == (i - player->currentBet)) {
turn.type = POKER_TURN_TYPE_CALL;
}
}
return turn;
}
// Winning
void pokerHandGetFull(
poker2_t *poker, poker2player_t *player, card_t cards[POKER_WINNING_FULL_SIZE]
) {
uint8_t i;
// Add the dealer hand
for(i = 0; i < poker->communitySize; i++) {
cards[i] = poker->community[i];
}
// Add the player hand
for(i = 0; i < player->cardCount; i++) {
cards[i+poker->communitySize] = player->cards[i];
}
}
void debug_WinnerFillRemaining(poker2playerwinning_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;
}
}
if(highest == 0xFF) break;
winning->set[winning->setSize++] = highestCard;
}
cardHandSort(winning->set, winning->setSize);
}
void pokerWinnerGetForPlayer(
poker2_t *poker, poker2player_t *player, poker2playerwinning_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->communitySize + player->cardCount;
pokerHandGetFull(poker, player, winning->full);
cardHandSort(winning->full, winning->fullSize);
// 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
);
debug_WinnerFillRemaining(winning);
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;
debug_WinnerFillRemaining(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;
debug_WinnerFillRemaining(winning);
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];
if(winning->setSize == POKER_WINNING_SET_SIZE) break;
}
if(winning->setSize < POKER_WINNING_SET_SIZE) continue;
winning->set[0] = winning->full[i];
winning->type = POKER_WINNING_TYPE_FLUSH;
debug_WinnerFillRemaining(winning);
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;
debug_WinnerFillRemaining(winning);
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;
debug_WinnerFillRemaining(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[winning->setSize+j] = winning->full[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;
debug_WinnerFillRemaining(winning);
return;
}
// Pair
if(winning->setSize == 2) {
winning->type = POKER_WINNING_TYPE_PAIR;
debug_WinnerFillRemaining(winning);
return;
}
// High card
winning->setSize = 0;
debug_WinnerFillRemaining(winning);
winning->type = POKER_WINNING_TYPE_HIGH_CARD;
return;
}
card_t debug_pokerWinnerCompare(poker2playerwinning_t *left, poker2playerwinning_t *right) {
uint8_t i, number;
card_t card;
int32_t index;
uint8_t countCardsSame;
card_t highCardLeft, highCardRight;
uint8_t highNumberLeft, highNumberRight;
highNumberLeft = 0xFF;
highNumberRight = 0xFF;
countCardsSame = 0;
for(i = 0; i < left->setSize; i++) {
card = left->set[i];
number = cardGetNumber(card);
if(highNumberLeft != 0xFF && number < highNumberLeft) continue;// Quick check
// Check if this number is within the other hand or not
index = cardContainsNumber(right->set, right->setSize, number);
if(index != -1) {
// This number IS within the other hand, let's check that the EXACT card
// is a match/isn't a match.
index = cardContains(right->set, right->setSize, card);
// Exact card match
if(index != -1) {
countCardsSame++;
continue;
}
// Not exact card match.. ?
}
if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberLeft < 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) {
index = cardContains(left->set, left->setSize, card);
if(index != -1) continue;
}
if(highNumberRight == 0xFF||number == CARD_ACE||highNumberRight < number) {
highNumberRight = number;
highCardRight = card;
}
}
if(countCardsSame == left->setSize) {
for(i = 0; i < left->setSize; i++) {
card = left->set[i];
number = cardGetNumber(card);
if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberLeft < number) {
highNumberLeft = number;
highCardLeft = card;
}
}
return highCardLeft;
}
if(highCardLeft == 0xFF) return 0xFF;
if(highNumberLeft < highNumberRight) return 0xFF;
return highCardLeft;//Greater or Equal to.
}
void pokerWinnerDetermineForPot(
poker2_t *poker,
poker2pot_t *pot,
poker2playerwinning_t winners[POKER_PLAYER_COUNT_MAX],
uint8_t winnerPlayers[POKER_PLAYER_COUNT_MAX],
uint8_t *winnerCount,
uint8_t participants[POKER_PLAYER_COUNT_MAX],
uint8_t *participantCount
) {
uint8_t i, j, countPlayers, countWinners, number, highNumber;
poker2playerwinning_t *left, *right;
poker2player_t *player;
card_t card, highCard;
bool isWinner;
countPlayers = 0;
countWinners = 0;
highCard = 0xFF;
// Get participating players and their hands.
for(i = 0; i < pot->playerCount; i++) {
player = poker->players + pot->players[i];
if(player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT)) {
continue;
}
participants[countPlayers] = pot->players[i];
pokerWinnerGetForPlayer(poker, player, winners + countPlayers++);
}
// Compare participating players
for(i = 0; i < countPlayers; i++) {
left = winners + i;
isWinner = true;
highNumber = 0xFF;
for(j = 0; j < countPlayers; j++) {
if(i == j) continue;
right = winners + j;
// 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 = debug_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;
winnerPlayers[countWinners++] = participants[i];
}
*participantCount = countPlayers;
*winnerCount = countWinners;
}
-171
View File
@@ -1,171 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#include "../util/flags.h"
#include "../util/array.h"
#include "../util/math.h"
#include "../poker/card.h"
#define POKER_PLAYER_COUNT_MAX 5
#define POKER_PLAYER_HAND_SIZE_MAX 2
#define POKER_PLAYER_STATE_FOLDED flagDefine(0)
#define POKER_PLAYER_STATE_OUT flagDefine(1)
#define POKER_PLAYER_STATE_HAS_BET_THIS_ROUND flagDefine(2)
#define POKER_GRAVE_SIZE_MAX CARD_DECK_SIZE
#define POKER_COMMUNITY_SIZE_MAX 5
#define POKER_POT_COUNT_MAX POKER_PLAYER_COUNT_MAX
#define POKER_TURN_TYPE_OUT 0x00
#define POKER_TURN_TYPE_FOLD 0x01
#define POKER_TURN_TYPE_BET 0x02
#define POKER_TURN_TYPE_CALL 0x03
#define POKER_TURN_TYPE_ALL_IN 0x04
#define POKER_TURN_TYPE_CALL_ALL_IN 0x04
#define POKER_TURN_TYPE_CHECK 0x05
#define POKER_WINNING_FULL_SIZE (\
POKER_PLAYER_HAND_SIZE_MAX+POKER_COMMUNITY_SIZE_MAX\
)
#define POKER_WINNING_SET_SIZE 5
#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_WINNING_TYPE_HIGH_CARD 0x0A
#define POKER_WINNING_CONFIDENCE_ROYAL_FLUSH 1.0f
#define POKER_WINNING_CONFIDENCE_STRAIGHT_FLUSH 0.99f
#define POKER_WINNING_CONFIDENCE_FOUR_OF_A_KIND 0.9f
#define POKER_WINNING_CONFIDENCE_FULL_HOUSE 0.85f
#define POKER_WINNING_CONFIDENCE_FLUSH 0.8f
#define POKER_WINNING_CONFIDENCE_STRAIGHT 0.7f
#define POKER_WINNING_CONFIDENCE_THREE_OF_A_KIND 0.5f
#define POKER_WINNING_CONFIDENCE_TWO_PAIR 0.4f
#define POKER_WINNING_CONFIDENCE_PAIR 0.2f
#define POKER_WINNING_CONFIDENCE_HIGH_CARD 0.1f
typedef struct {
int32_t chips;
card_t cards[POKER_PLAYER_HAND_SIZE_MAX];
uint8_t cardCount;
uint8_t state;
int32_t currentBet;
} poker2player_t;
/** 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;
} poker2playerwinning_t;
typedef struct {
int32_t chips;
uint8_t players[POKER_PLAYER_COUNT_MAX];
uint8_t playerCount;
} poker2pot_t;
typedef struct {
uint8_t type;
int32_t chips;
float confidence;
} poker2turn_t;
typedef struct {
card_t deck[CARD_DECK_SIZE];
uint8_t deckSize;
card_t grave[POKER_GRAVE_SIZE_MAX];
uint8_t graveSize;
card_t community[POKER_COMMUNITY_SIZE_MAX];
uint8_t communitySize;
poker2pot_t pots[POKER_POT_COUNT_MAX];
uint8_t potCount;
poker2player_t players[POKER_PLAYER_COUNT_MAX];
uint8_t playerCount;
uint8_t playerDealer;
uint8_t playerSmallBlind;
uint8_t playerBigBlind;
} poker2_t;
void pokerInit(poker2_t *poker);
void pokerResetRound(poker2_t *poker);
void pokerNewDealer(poker2_t *poker);
void pokerTakeBlinds(poker2_t *poker, int32_t small, int32_t big);
int32_t pokerGetCallValue(poker2_t *poker);
uint8_t pokerPotAdd(poker2_t *poker);
void pokerPotAddPlayer(poker2pot_t *pot, uint8_t playerIndex);
void pokerTurn(poker2_t *poker, uint8_t count);
void pokerBurn(poker2_t *poker, uint8_t count);
uint8_t pokerPlayerAdd(poker2_t *poker);
void pokerPlayerDeal(poker2_t *poker, poker2player_t *player, uint8_t count);
void pokerPlayerChipsAdd(poker2player_t *player, int32_t chips);
void pokerPlayerDealAll(poker2_t *poker, uint8_t count);
bool pokerPlayerDoesNeedToBetThisRound(poker2_t *poker, uint8_t playerIndex);
uint8_t pokerPlayerGetRemainingBetter(poker2_t *poker);
uint8_t pokerPlayerGetNextBetter(poker2_t *poker, uint8_t current);
int32_t pokerPlayerGetCallBet(poker2_t *poker, poker2player_t *player);
void pokerPlayerBetPot(
poker2_t *poker, poker2pot_t *pot, uint8_t playerIndex, int32_t chips
);
void pokerPlayerBet(poker2_t *poker, uint8_t playerIndex, int32_t chips);
bool pokerPlayerCanCheck(poker2_t *poker, poker2player_t *player);
poker2turn_t pokerTurnFold(poker2_t *poker, uint8_t player);
poker2turn_t pokerTurnBet(poker2_t *poker, uint8_t playerIndex, int32_t chips);
void pokerHandGetFull(
poker2_t *poker, poker2player_t *player, card_t cards[POKER_WINNING_FULL_SIZE]
);
void debug_WinnerFillRemaining(poker2playerwinning_t *winning);
void pokerWinnerGetForPlayer(
poker2_t *poker, poker2player_t *player, poker2playerwinning_t *winning
);
card_t debug_pokerWinnerCompare(poker2playerwinning_t *left, poker2playerwinning_t *right);
void pokerWinnerDetermineForPot(
poker2_t *poker,
poker2pot_t *pot,
poker2playerwinning_t winners[POKER_PLAYER_COUNT_MAX],
uint8_t winnerPlayers[POKER_PLAYER_COUNT_MAX],
uint8_t *winnerCount,
uint8_t participants[POKER_PLAYER_COUNT_MAX],
uint8_t *participantCount
);
+148 -101
View File
@@ -8,7 +8,7 @@
#include "poker.h"
void test_pokerInit_should_InitializePokerGame(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
TEST_ASSERT_EQUAL_UINT8(0, poker.playerCount);
TEST_ASSERT_EQUAL_UINT8(0, poker.playerDealer);
@@ -17,7 +17,7 @@ void test_pokerInit_should_InitializePokerGame(void) {
}
void test_pokerResetRound_should_ResetTheRound(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
poker.potCount = 0x03;
@@ -34,7 +34,7 @@ void test_pokerResetRound_should_ResetTheRound(void) {
}
void test_pokerResetRound_should_ResetThePlayers(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
pokerInit(&poker);
@@ -56,7 +56,10 @@ void test_pokerResetRound_should_ResetThePlayers(void) {
TEST_ASSERT_EQUAL_INT32(0, poker.players[i].currentBet);
TEST_ASSERT_EQUAL_INT32(100, poker.players[i].chips);
TEST_ASSERT_BITS_LOW(POKER_PLAYER_STATE_FOLDED, poker.players[i].state);
TEST_ASSERT_BITS_LOW(POKER_PLAYER_STATE_HAS_BET_THIS_ROUND, poker.players[i].state);
TEST_ASSERT_BITS_LOW(
POKER_PLAYER_STATE_HAS_BET_THIS_ROUND, poker.players[i].state
);
TEST_ASSERT_BITS_LOW(POKER_PLAYER_STATE_SHOWING, poker.players[i].state);
TEST_ASSERT_EQUAL_UINT8(
0xFF - POKER_PLAYER_STATE_FOLDED - POKER_PLAYER_STATE_HAS_BET_THIS_ROUND,
poker.players[i].state
@@ -65,7 +68,7 @@ void test_pokerResetRound_should_ResetThePlayers(void) {
}
void test_pokerNewDealer_should_FindANewDealer(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 1000);
@@ -101,7 +104,7 @@ void test_pokerNewDealer_should_FindANewDealer(void) {
void test_pokerNewDealer_should_SkipOutPlayers(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 1000);
@@ -127,7 +130,7 @@ void test_pokerNewDealer_should_SkipOutPlayers(void) {
}
void test_pokerTakeBlinds_should_TakeTheBlinds(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 1000);
@@ -163,7 +166,7 @@ void test_pokerTakeBlinds_should_TakeTheBlinds(void) {
}
void test_pokerPotAdd_should_AddAPot(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
TEST_ASSERT_EQUAL_UINT8(1, poker.potCount);
@@ -172,8 +175,8 @@ void test_pokerPotAdd_should_AddAPot(void) {
}
void test_pokerPotAdd_should_ResetThePot(void) {
poker2_t poker;
poker2pot_t *pot;
poker_t poker;
pokerpot_t *pot;
uint8_t i;
pokerInit(&poker);
@@ -184,8 +187,8 @@ void test_pokerPotAdd_should_ResetThePot(void) {
}
void test_pokerPotAddPlayer_should_AddAPlayer(void) {
poker2_t poker;
poker2pot_t *pot;
poker_t poker;
pokerpot_t *pot;
pokerInit(&poker);
pokerPlayerAdd(&poker);
@@ -204,7 +207,7 @@ void test_pokerPotAddPlayer_should_AddAPlayer(void) {
}
void test_pokerPlayerAdd_should_AddAPlayer(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
TEST_ASSERT_EQUAL_UINT8(0, poker.playerCount);
@@ -215,8 +218,8 @@ void test_pokerPlayerAdd_should_AddAPlayer(void) {
}
void test_pokerPlayerAdd_should_ResetThePlayer(void) {
poker2_t poker;
poker2player_t *player;
poker_t poker;
pokerplayer_t *player;
pokerInit(&poker);
player = poker.players + pokerPlayerAdd(&poker);
@@ -227,7 +230,7 @@ void test_pokerPlayerAdd_should_ResetThePlayer(void) {
}
void test_pokerTurn_should_TurnCardsFromTheDeck(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
TEST_ASSERT_EQUAL_UINT8(CARD_DECK_SIZE, poker.deckSize);
@@ -247,7 +250,7 @@ void test_pokerTurn_should_TurnCardsFromTheDeck(void) {
}
void test_pokerBurn_should_SendCardsToTheGrave(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
TEST_ASSERT_EQUAL_UINT8(CARD_DECK_SIZE, poker.deckSize);
@@ -268,7 +271,7 @@ void test_pokerBurn_should_SendCardsToTheGrave(void) {
}
void test_pokerGetCallValue_should_CalculateTheCallValue(void) {
poker2_t poker;
poker_t poker;
uint8_t first, second;
pokerInit(&poker);
first = pokerPlayerAdd(&poker);
@@ -291,7 +294,7 @@ void test_pokerGetCallValue_should_CalculateTheCallValue(void) {
}
void test_pokerGetCallValue_should_SkipOutPlayers(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
pokerInit(&poker);
@@ -315,9 +318,9 @@ void test_pokerGetCallValue_should_SkipOutPlayers(void) {
}
void test_pokerPlayerDeal_should_DealCardsToThePlayer(void) {
poker2_t poker;
poker_t poker;
uint8_t playerIndex;
poker2player_t *player;
pokerplayer_t *player;
pokerInit(&poker);
@@ -339,9 +342,9 @@ void test_pokerPlayerDeal_should_DealCardsToThePlayer(void) {
}
void test_pokerPlayerChipsAdd_should_AddChipsToThePlayer(void) {
poker2_t poker;
poker_t poker;
uint8_t playerIndex;
poker2player_t *player;
pokerplayer_t *player;
pokerInit(&poker);
playerIndex = pokerPlayerAdd(&poker);
@@ -357,9 +360,9 @@ void test_pokerPlayerChipsAdd_should_AddChipsToThePlayer(void) {
}
void test_pokerPlayerChipsAdd_should_TurnOutStateOff(void) {
poker2_t poker;
poker_t poker;
uint8_t playerIndex;
poker2player_t *player;
pokerplayer_t *player;
pokerInit(&poker);
playerIndex = pokerPlayerAdd(&poker);
@@ -372,7 +375,7 @@ void test_pokerPlayerChipsAdd_should_TurnOutStateOff(void) {
}
void test_pokerPlayerDealAll_should_DealCardsToEveryone(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 100);
@@ -396,7 +399,7 @@ void test_pokerPlayerDealAll_should_DealCardsToEveryone(void) {
}
void test_pokerPlayerDealAll_should_DealMultipleCardsToEveryone(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 100);
@@ -420,7 +423,7 @@ void test_pokerPlayerDealAll_should_DealMultipleCardsToEveryone(void) {
}
void test_pokerPlayerDealAll_should_NotDealToOutPlayers(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 100);
@@ -442,7 +445,7 @@ void test_pokerPlayerDealAll_should_NotDealToOutPlayers(void) {
}
void test_pokerPlayerDealAll_should_NotDealToFoldedPlayers(void) {
poker2_t poker;
poker_t poker;
pokerInit(&poker);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 100);
@@ -462,7 +465,7 @@ void test_pokerPlayerDealAll_should_NotDealToFoldedPlayers(void) {
}
void test_pokerPlayerDoesNeedToBetThisRound_should_CheckCallValue(void) {
poker2_t poker;
poker_t poker;
uint8_t first, second;
pokerInit(&poker);
@@ -486,7 +489,7 @@ void test_pokerPlayerDoesNeedToBetThisRound_should_CheckCallValue(void) {
}
void test_pokerPlayerDoesNeedToBetThisRound_should_CheckWhetherHasBetYet(void) {
poker2_t poker;
poker_t poker;
uint8_t first, second;
pokerInit(&poker);
first = pokerPlayerAdd(&poker);
@@ -507,7 +510,7 @@ void test_pokerPlayerDoesNeedToBetThisRound_should_CheckWhetherHasBetYet(void) {
}
void test_pokerPlayerDoesNeedToBetThisRound_should_IgnoreFoldedPlayers(void) {
poker2_t poker;
poker_t poker;
uint8_t first, second;
pokerInit(&poker);
first = pokerPlayerAdd(&poker);
@@ -532,7 +535,7 @@ void test_pokerPlayerDoesNeedToBetThisRound_should_IgnoreFoldedPlayers(void) {
}
void test_pokerPlayerGetRemainingBetter_should_ReturnRemainingBetters(void) {
poker2_t poker;
poker_t poker;
uint8_t p0, p1, p2, p3, p4;
pokerInit(&poker);
@@ -585,7 +588,7 @@ void test_pokerPlayerGetRemainingBetter_should_ReturnRemainingBetters(void) {
}
void test_pokerPlayerGetNextBetter_should_GetTheNextBetter(void) {
poker2_t poker;
poker_t poker;
uint8_t p0, p1, p2, p3, p4;
uint8_t better;
pokerInit(&poker);
@@ -650,7 +653,7 @@ void test_pokerPlayerGetNextBetter_should_GetTheNextBetter(void) {
}
void test_pokerPlayerGetCallBet_should_GetCallBet(void) {
poker2_t poker;
poker_t poker;
uint8_t p0, p1, p2;
pokerInit(&poker);
@@ -675,9 +678,9 @@ void test_pokerPlayerGetCallBet_should_GetCallBet(void) {
}
void test_pokerPlayerBetPot_should_AddChipsToThePot(void) {
poker2_t poker;
poker2pot_t *pot;
poker2player_t *player;
poker_t poker;
pokerpot_t *pot;
pokerplayer_t *player;
uint8_t i;
pokerInit(&poker);
@@ -695,9 +698,9 @@ void test_pokerPlayerBetPot_should_AddChipsToThePot(void) {
}
void test_pokerPlayerBetPot_should_UpdatePlayerState(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
pokerplayer_t *player;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -716,8 +719,8 @@ void test_pokerPlayerBetPot_should_UpdatePlayerState(void) {
}
void test_pokerPlayerBet_should_BetToTheActivePot(void) {
poker2_t poker;
poker2pot_t *pot;
poker_t poker;
pokerpot_t *pot;
uint8_t i, j;
pokerInit(&poker);
@@ -737,7 +740,7 @@ void test_pokerPlayerBet_should_BetToTheActivePot(void) {
}
void test_pokerPlayerCanCheck_should_CompareThePotAndPlayerBet(void) {
poker2_t poker;
poker_t poker;
uint8_t p0, p1, p2;
pokerInit(&poker);
@@ -775,8 +778,8 @@ void test_pokerPlayerCanCheck_should_CompareThePotAndPlayerBet(void) {
}
void test_pokerTurnFold_should_ReturnAFoldAction(void) {
poker2_t poker;
poker2turn_t turn;
poker_t poker;
pokerturn_t turn;
pokerInit(&poker);
pokerPlayerAdd(&poker);
@@ -787,8 +790,8 @@ void test_pokerTurnFold_should_ReturnAFoldAction(void) {
}
void test_pokerTurnBet_should_ReturnACheckAction(void) {
poker2_t poker;
poker2turn_t turn;
poker_t poker;
pokerturn_t turn;
pokerInit(&poker);
pokerPlayerAdd(&poker);
@@ -799,8 +802,8 @@ void test_pokerTurnBet_should_ReturnACheckAction(void) {
}
void test_pokerTurnBet_should_ReturnAnAllInAction(void) {
poker2_t poker;
poker2turn_t turn;
poker_t poker;
pokerturn_t turn;
pokerInit(&poker);
pokerPlayerAdd(&poker);
pokerPlayerChipsAdd(poker.players, 500);
@@ -818,8 +821,8 @@ void test_pokerTurnBet_should_ReturnAnAllInAction(void) {
}
void test_pokerTurnBet_should_ReturnACallAction(void) {
poker2_t poker;
poker2turn_t turn;
poker_t poker;
pokerturn_t turn;
pokerInit(&poker);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 1000);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 1000);
@@ -840,8 +843,8 @@ void test_pokerTurnBet_should_ReturnACallAction(void) {
}
void test_pokerTurnBet_should_ReturnARaiseAction(void) {
poker2_t poker;
poker2turn_t turn;
poker_t poker;
pokerturn_t turn;
pokerInit(&poker);
pokerPlayerChipsAdd(poker.players + pokerPlayerAdd(&poker), 1000);
@@ -857,8 +860,8 @@ void test_pokerTurnBet_should_ReturnARaiseAction(void) {
}
void test_pokerHandGetFull_should_ReturnTheFullHand(void) {
poker2_t poker;
poker2player_t *player;
poker_t poker;
pokerplayer_t *player;
uint8_t i;
card_t cards[POKER_WINNING_FULL_SIZE];
@@ -905,7 +908,7 @@ void test_pokerHandGetFull_should_ReturnTheFullHand(void) {
}
void test_pokerWinnerFillRemaining_should_FillTheRestOfTheArray(void) {
poker2playerwinning_t winning;
pokerplayerwinning_t winning;
winning.fullSize = 7;
winning.full[0] = CARD_CLUBS_ACE;
winning.full[1] = CARD_CLUBS_TWO;
@@ -920,7 +923,7 @@ void test_pokerWinnerFillRemaining_should_FillTheRestOfTheArray(void) {
winning.setSize = 1;
winning.set[0] = CARD_CLUBS_ACE;
debug_WinnerFillRemaining(&winning);
pokerWinnerFillRemaining(&winning);
TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_SET_SIZE, winning.setSize);
TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_ACE, winning.set[0]);
TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_SEVEN, winning.set[1]);
@@ -930,10 +933,10 @@ void test_pokerWinnerFillRemaining_should_FillTheRestOfTheArray(void) {
}
void test_pokerWinnerGetForPlayer_should_CalculateHighCard(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -963,10 +966,10 @@ void test_pokerWinnerGetForPlayer_should_CalculateHighCard(void) {
}
void test_pokerWinnerGetForPlayer_should_CalculatePair(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -1008,10 +1011,10 @@ void test_pokerWinnerGetForPlayer_should_CalculatePair(void) {
}
void test_pokerWinnerGetForPlayer_should_CalculateTwoPair(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -1037,10 +1040,10 @@ void test_pokerWinnerGetForPlayer_should_CalculateTwoPair(void) {
}
void test_pokerWinnerGetForPlayer_should_CalculateThreeOfAKind(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -1066,10 +1069,10 @@ void test_pokerWinnerGetForPlayer_should_CalculateThreeOfAKind(void) {
}
void test_pokerWinnerGetForPlayer_should_CalculateAStraight(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -1095,10 +1098,10 @@ void test_pokerWinnerGetForPlayer_should_CalculateAStraight(void) {
}
void test_pokerWinnerGetForPlayer_should_CalculateAFlush(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -1124,10 +1127,10 @@ void test_pokerWinnerGetForPlayer_should_CalculateAFlush(void) {
}
void test_pokerWinnerGet_should_CalculateFullHouse(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -1153,10 +1156,10 @@ void test_pokerWinnerGet_should_CalculateFullHouse(void) {
}
void test_pokerWinnerGetForPlayer_should_CalculateFourOfAKind(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -1182,10 +1185,10 @@ void test_pokerWinnerGetForPlayer_should_CalculateFourOfAKind(void) {
}
void test_pokerWinnerGetForPlayer_should_CalculateStraightFlush(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -1211,10 +1214,10 @@ void test_pokerWinnerGetForPlayer_should_CalculateStraightFlush(void) {
}
void test_pokerWinnerGetForPlayer_should_CalculateRoyalFlush(void) {
poker2_t poker;
poker_t poker;
uint8_t i;
poker2player_t *player;
poker2playerwinning_t winning;
pokerplayer_t *player;
pokerplayerwinning_t winning;
pokerInit(&poker);
i = pokerPlayerAdd(&poker);
@@ -1240,11 +1243,11 @@ void test_pokerWinnerGetForPlayer_should_CalculateRoyalFlush(void) {
}
void test_pokerWinnerCompare_should_CompareWinningHands(void) {
poker2_t poker;
poker_t poker;
uint8_t p0i, p1i;
poker2player_t *p0;
poker2player_t *p1;
poker2playerwinning_t w0, w1;
pokerplayer_t *p0;
pokerplayer_t *p1;
pokerplayerwinning_t w0, w1;
card_t kicker;
// Construct two hands of the same type (pairs of eights)
@@ -1277,7 +1280,7 @@ void test_pokerWinnerCompare_should_CompareWinningHands(void) {
TEST_ASSERT_EQUAL_UINT8(w0.type, w1.type);
// Get the kicker, should be the king.
kicker = debug_pokerWinnerCompare(&w0, &w1);
kicker = pokerWinnerCompare(&w0, &w1);
TEST_ASSERT_EQUAL_UINT8(CARD_CLUBS_KING, kicker);
// Change the kickers
@@ -1285,48 +1288,53 @@ void test_pokerWinnerCompare_should_CompareWinningHands(void) {
p1->cards[1] = CARD_CLUBS_KING;
pokerWinnerGetForPlayer(&poker, p0, &w0);
pokerWinnerGetForPlayer(&poker, p1, &w1);
kicker = debug_pokerWinnerCompare(&w0, &w1);
kicker = pokerWinnerCompare(&w0, &w1);
TEST_ASSERT_EQUAL_UINT8(CARD_HEARTS_ACE, kicker);
// Low left weight
p0->cards[1] = CARD_HEARTS_JACK;
pokerWinnerGetForPlayer(&poker, p0, &w0);
kicker = debug_pokerWinnerCompare(&w0, &w1);
kicker = pokerWinnerCompare(&w0, &w1);
TEST_ASSERT_EQUAL_UINT8(0xFF, kicker);
}
void test_pokerWinnerDetermine_should_DecideTheWinnerCorrectly(void) {
poker2_t poker;
uint8_t p0i, p1i;
poker2player_t *p0;
poker2player_t *p1;
poker_t poker;
uint8_t p0i, p1i, p2i;
pokerplayer_t *p0;
pokerplayer_t *p1;
pokerplayer_t *p2;
// Outputs
uint8_t winnerCount, participantCount;
uint8_t winnerPlayers[POKER_PLAYER_COUNT_MAX];
uint8_t participants[POKER_PLAYER_COUNT_MAX];
poker2playerwinning_t winners[POKER_PLAYER_COUNT_MAX];
pokerplayerwinning_t winners[POKER_PLAYER_COUNT_MAX];
// Set up the players
pokerInit(&poker);
p0i = pokerPlayerAdd(&poker);
p1i = pokerPlayerAdd(&poker);
p2i = pokerPlayerAdd(&poker);
p0 = poker.players + p0i;
p1 = poker.players + p1i;
p2 = poker.players + p2i;
pokerPotAddPlayer(poker.pots + 0, p0i);
pokerPotAddPlayer(poker.pots + 0, p1i);
pokerPotAddPlayer(poker.pots + 0, p2i);
pokerPlayerChipsAdd(p0, 10000);
pokerPlayerChipsAdd(p1, 10000);
pokerPlayerChipsAdd(p2, 10000);
// Set up the community
poker.communitySize = 5;
poker.community[0] = CARD_HEARTS_TWO;
poker.community[1] = CARD_DIAMONDS_NINE;
poker.community[2] = CARD_DIAMONDS_FOUR;
poker.community[3] = CARD_CLUBS_SIX;
poker.community[3] = CARD_DIAMONDS_SIX;
poker.community[4] = CARD_HEARTS_EIGHT;
// Set up the player hands
@@ -1338,6 +1346,11 @@ void test_pokerWinnerDetermine_should_DecideTheWinnerCorrectly(void) {
p1->cards[0] = CARD_SPADES_EIGHT;
p1->cards[1] = CARD_CLUBS_QUEEN;//Low, not
p2->state |= POKER_PLAYER_STATE_FOLDED;// Start folded
p2->cardCount = 2;
p2->cards[0] = CARD_DIAMONDS_TWO;
p2->cards[1] = CARD_DIAMONDS_KING;
// Run first test.
pokerWinnerDetermineForPot(
&poker, poker.pots + 0,
@@ -1369,10 +1382,44 @@ void test_pokerWinnerDetermine_should_DecideTheWinnerCorrectly(void) {
TEST_ASSERT_EQUAL_UINT8(1, winnerPlayers[0]);
TEST_ASSERT_EQUAL_UINT8(0, participants[0]);
TEST_ASSERT_EQUAL_UINT8(1, participants[1]);
// Unfold p2
p2->state = flagOff(p2->state, POKER_PLAYER_STATE_FOLDED);
pokerWinnerDetermineForPot(
&poker, poker.pots + 0,
winners, winnerPlayers, &winnerCount,
participants, &participantCount
);
TEST_ASSERT_EQUAL_UINT8(1, winnerCount);
TEST_ASSERT_EQUAL_UINT8(3, participantCount);
TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, winners[0].type);
TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_TWO_PAIR, winners[1].type);
TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_FLUSH, winners[2].type);
TEST_ASSERT_EQUAL_UINT8(2, winnerPlayers[0]);
TEST_ASSERT_EQUAL_UINT8(0, participants[0]);
TEST_ASSERT_EQUAL_UINT8(1, participants[1]);
TEST_ASSERT_EQUAL_UINT8(2, participants[2]);
// Create a new pot that P2 isn't participating in.
pokerPotAdd(&poker);
pokerPotAddPlayer(poker.pots + 1, p0i);
pokerPotAddPlayer(poker.pots + 1, p1i);
pokerWinnerDetermineForPot(
&poker, poker.pots + 1,
winners, winnerPlayers, &winnerCount,
participants, &participantCount
);
TEST_ASSERT_EQUAL_UINT8(1, winnerCount);
TEST_ASSERT_EQUAL_UINT8(2, participantCount);
TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_PAIR, winners[0].type);
TEST_ASSERT_EQUAL_UINT8(POKER_WINNING_TYPE_TWO_PAIR, winners[1].type);
TEST_ASSERT_EQUAL_UINT8(1, winnerPlayers[0]);
TEST_ASSERT_EQUAL_UINT8(0, participants[0]);
TEST_ASSERT_EQUAL_UINT8(1, participants[1]);
}
int test_poker2() {
int test_poker() {
UNITY_BEGIN();
RUN_TEST(test_pokerInit_should_InitializePokerGame);
File renamed without changes.