Fixed betting bugs.

This commit is contained in:
2021-09-27 14:27:13 -07:00
parent 733c311d5e
commit d4cc907506
22 changed files with 169 additions and 62 deletions

View File

@ -86,11 +86,8 @@ void _pokerGameActionBetOnUpdate(
void _pokerGameActionBetOnEnd( void _pokerGameActionBetOnEnd(
queue_t *queue, queueaction_t *action, uint8_t i queue_t *queue, queueaction_t *action, uint8_t i
) { ) {
queueaction_t *next;
pokerdiscussiondata_t discussion;
pokergame_t *game = (pokergame_t *)action->data; pokergame_t *game = (pokergame_t *)action->data;
// Get which player is remaining to move. // Get which player is remaining to move.
game->poker.bet.better = pokerBetGetRemainingPlayer( game->poker.bet.better = pokerBetGetRemainingPlayer(
&game->poker.bet, game->poker.players, game->poker.roundSmallBlind &game->poker.bet, game->poker.players, game->poker.roundSmallBlind
@ -101,47 +98,14 @@ void _pokerGameActionBetOnEnd(
// Are we waiting on any players? // Are we waiting on any players?
if(game->poker.bet.better != 0xFF) { if(game->poker.bet.better != 0xFF) {
if(game->poker.bet.better == POKER_PLAYER_HUMAN_INDEX) { pokerGameActionLookAdd(game, game->poker.bet.better);
pokerGameActionLookAdd(game, POKER_DEALER_INDEX);
} else {
pokerGameActionLookAdd(game, game->poker.bet.better);
}
pokerGameActionBetAdd(game); pokerGameActionBetAdd(game);
return; return;
} }
// Prep convo // Not waiting, do next action.
discussion.poker = game;
// Not waiting, restack and do next action.
printf("Not waiting on anything!\n"); printf("Not waiting on anything!\n");
pokerGameActionFlopAdd(game);
// Is there a next round, or did someone just win?
if(pokerBetGetRemainingPlayerCount(&game->poker.bet,game->poker.players) > 1){
// No! Begin the next flop.
next = pokerActionNextFlopAdd(queue, &game->poker);
if(next != NULL) {
discussion.reason = POKER_DISCUSSION_REASON_FLOP;
pokerDiscussionQueue(&discussion);
pokerBetResetBetter(
&game->poker.bet, game->poker.players, game->poker.roundSmallBlind
);
pokerGameActionRestackAdd(game);
pokerGameActionLookAdd(game, game->poker.bet.better);
pokerGameActionBetAdd(game);
return;
}
}
// Done betting
printf("All betting is done, reveal\n");
discussion.reason = POKER_DISCUSSION_REASON_BETTING_DONE;
discussion.poker = game;
pokerDiscussionQueue(&discussion);
pokerGameActionRestackAdd(game);
pokerGameActionWinnerAdd(game);
} }
queueaction_t * pokerGameActionBetAdd(pokergame_t *game) { queueaction_t * pokerGameActionBetAdd(pokergame_t *game) {

View File

@ -14,6 +14,7 @@
#include "action.h" #include "action.h"
#include "restack.h" #include "restack.h"
#include "winner.h" #include "winner.h"
#include "flop.h"
/** Callback when the bet action is updated. */ /** Callback when the bet action is updated. */
void _pokerGameActionBetOnUpdate( void _pokerGameActionBetOnUpdate(

View File

@ -0,0 +1,25 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#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"
#include "winner.h"
#include "bet.h"
/**
* Queues a flop action on to the queue.
*
* @param game Game to queue on to.
* @return queueaction_t*
*/
queueaction_t * pokerGameActionFlopAdd(pokergame_t *game);

View File

@ -10,7 +10,10 @@
void _pokerGameActionWinnerOnStart( void _pokerGameActionWinnerOnStart(
queue_t *queue, queueaction_t *action, uint8_t i queue_t *queue, queueaction_t *action, uint8_t i
) { ) {
pokerdiscussiondata_t discussion;
pokergame_t *game = (pokergame_t *)action->data; pokergame_t *game = (pokergame_t *)action->data;
// Calculate the winners
printf("Winner start action"); printf("Winner start action");
pokerWinnerCalculate( pokerWinnerCalculate(
&game->poker.winner, &game->poker.winner,
@ -18,12 +21,22 @@ void _pokerGameActionWinnerOnStart(
game->poker.players game->poker.players
); );
// Action
pokerGameWin(&game->poker);
// Debug printing.
printf("Winner Count %u\n", game->poker.winner.winnerCount); printf("Winner Count %u\n", game->poker.winner.winnerCount);
for(uint8_t i = 0; i < game->poker.winner.winnerCount; i++) { for(uint8_t i = 0; i < game->poker.winner.winnerCount; i++) {
uint8_t winner = game->poker.winner.winners[i]; uint8_t winner = game->poker.winner.winners[i];
printf("Winner %u\n", winner); printf("Winner %u\n", winner);
} }
// Say stuff
discussion.reason = POKER_DISCUSSION_REASON_BETTING_DONE;
discussion.poker = game;
pokerDiscussionQueue(&discussion);
// Begin next round.
pokerGameActionRoundAdd(game); pokerGameActionRoundAdd(game);
queueNext(queue); queueNext(queue);
} }

View File

@ -8,6 +8,7 @@
#pragma once #pragma once
#include "../../../libs.h" #include "../../../libs.h"
#include "../../../poker/winner.h" #include "../../../poker/winner.h"
#include "../../../poker/poker.h"
#include "../pokerdiscussion.h" #include "../pokerdiscussion.h"
#include "action.h" #include "action.h"
#include "round.h" #include "round.h"

View File

@ -106,8 +106,10 @@ void pokerDiscussionQueue(pokerdiscussiondata_t *data) {
pokerdiscussion_t discussion; pokerdiscussion_t discussion;
uint8_t i, player; uint8_t i, player;
// Fetch the discussion item for the given data.
pokerDiscussionGet(&discussion, data); pokerDiscussionGet(&discussion, data);
// Now for each discussion item, queue a task.
for(i = 0; i < discussion.count; i++) { for(i = 0; i < discussion.count; i++) {
player = discussion.players[i]; player = discussion.players[i];

View File

@ -8,6 +8,7 @@
#pragma once #pragma once
#include "../../libs.h" #include "../../libs.h"
/** Representation of data that poker game actions can have access to. */
typedef struct { typedef struct {
uint8_t lookAtPlayer; uint8_t lookAtPlayer;
} pokergameactiondata_t; } pokergameactiondata_t;

View File

@ -10,9 +10,7 @@
void _pokerActionBlindsOnStart(queue_t *queue,queueaction_t *action,uint8_t i) { void _pokerActionBlindsOnStart(queue_t *queue,queueaction_t *action,uint8_t i) {
poker_t *poker; poker_t *poker;
poker = (poker_t *)action->data; poker = (poker_t *)action->data;
poker->state = POKER_STATE_TAKING_BLINDS; poker->state = POKER_STATE_TAKING_BLINDS;
pokerBetTakeBlinds( pokerBetTakeBlinds(
&poker->bet, &poker->bet,
poker->players, poker->players,

View File

@ -11,9 +11,9 @@ void _pokerActionDealOnStart(queue_t *queue, queueaction_t *action, uint8_t i) {
poker_t *poker; poker_t *poker;
poker = (poker_t *)action->data; poker = (poker_t *)action->data;
poker->state = POKER_STATE_DEALING;
// Shuffle the deck // Shuffle the deck
poker->state = POKER_STATE_DEALING;
cardShuffle(poker->dealer.deck, CARD_DECK_SIZE); cardShuffle(poker->dealer.deck, CARD_DECK_SIZE);
// Deal 2 card to each player // Deal 2 card to each player

View File

@ -30,13 +30,14 @@ void _pokerActionRoundOnStart(queue_t *queue, queueaction_t *action ,uint8_t i){
// Decide on the dealer // Decide on the dealer
poker->roundDealer = (poker->roundDealer+1) % POKER_PLAYER_COUNT; poker->roundDealer = (poker->roundDealer+1) % POKER_PLAYER_COUNT;
// Find the players. // Find (and kill) the players.
j = poker->roundDealer; j = poker->roundDealer;
foundDealer = false; foundDealer = false;
foundSmallBlind = false; foundSmallBlind = false;
while(true) { while(true) {
player = poker->players + j; player = poker->players + j;
if(!pokerPlayerIsAlive(player)) continue;
if(!pokerPlayerIsInRound(player)) continue;
if(!foundDealer) { if(!foundDealer) {
indexDealer = j; indexDealer = j;
foundDealer = true; foundDealer = true;

View File

@ -42,10 +42,17 @@ void pokerBetResetBetter(
} }
bool pokerBetPlayerCanBet(pokerbet_t *bet, pokerplayer_t *player) { bool pokerBetPlayerCanBet(pokerbet_t *bet, pokerplayer_t *player) {
if(!pokerPlayerIsAlive(player)) return false; // Is the player out?
if(!pokerPlayerIsInRound(player)) return false;
// Is the player broke?
if(player->chips <= 0) return false;
// Does the player still need to act yet?
if(player->state & POKER_PLAYER_STATE_ROUND_MOVE) { if(player->state & POKER_PLAYER_STATE_ROUND_MOVE) {
if(player->currentBet >= bet->currentBet && player) return false; if(player->currentBet >= bet->currentBet) return false;
} }
return true; return true;
} }
@ -66,7 +73,7 @@ uint8_t pokerBetGetRemainingPlayerCount(pokerbet_t *bet,pokerplayer_t *players){
uint8_t i, c; uint8_t i, c;
c = 0; c = 0;
for(i = 0; i < POKER_PLAYER_COUNT; i++) { for(i = 0; i < POKER_PLAYER_COUNT; i++) {
if(!pokerPlayerIsAlive(players + i)) continue; if(!pokerBetPlayerCanBet(bet, players + i)) continue;
c++; c++;
} }
return c; return c;

View File

@ -7,6 +7,7 @@
#include "../libs.h" #include "../libs.h"
#include "player.h" #include "player.h"
#include "../util/math.h" #include "../util/math.h"
#include "../util/array.h"
/** How many chips each player has by defautl */ /** How many chips each player has by defautl */
#define POKER_BET_PLAYER_CHIPS_DEFAULT 10000 #define POKER_BET_PLAYER_CHIPS_DEFAULT 10000
@ -41,7 +42,7 @@ void pokerBetInit(pokerbet_t *bet);
/** /**
* Resets the bet state (for a new round). * Resets the bet state (for a new round).
* *
* @param bet * @param bet Betting stating.
*/ */
void pokerBetReset(pokerbet_t *bet); void pokerBetReset(pokerbet_t *bet);
@ -97,8 +98,7 @@ uint8_t pokerBetGetRemainingPlayer(
); );
/** /**
* Returns the count of players who are still available to bet. This does not * Returns the count of players who are still needing to bet.
* consider any round logic, simply whether or not they COULD bet.
* *
* @param bet Betting instance * @param bet Betting instance
* @param players Players array. * @param players Players array.

View File

@ -48,7 +48,7 @@ void pokerDealerDealAll(
for(y = 0; y < count; y++) { for(y = 0; y < count; y++) {
for(x = 0; x < POKER_PLAYER_COUNT; x++) { for(x = 0; x < POKER_PLAYER_COUNT; x++) {
player = players + x; player = players + x;
if(!pokerPlayerIsAlive(player)) continue; if(!pokerPlayerIsInRound(player)) continue;
pokerDealerDeal(dealer, player); pokerDealerDeal(dealer, player);
} }
} }

View File

@ -7,8 +7,19 @@
#include "player.h" #include "player.h"
bool pokerPlayerIsAlive(pokerplayer_t *player) { bool pokerPlayerIsInRound(pokerplayer_t *player) {
return !(player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT)); return !(
player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT)
);
}
uint8_t pokerPlayerGetCountInRound(pokerplayer_t *players) {
return (uint8_t)arraySum(
sizeof(pokerplayer_t),
players,
POKER_PLAYER_COUNT,
(arraysumcallback_t *)(&pokerPlayerIsInRound)
);
} }
void pokerPlayerReset(pokerplayer_t *player) { void pokerPlayerReset(pokerplayer_t *player) {

View File

@ -8,6 +8,7 @@
#pragma once #pragma once
#include "../libs.h" #include "../libs.h"
#include "../util/flags.h" #include "../util/flags.h"
#include "../util/array.h"
#include "card.h" #include "card.h"
/** How many cards a player can hold in their hand */ /** How many cards a player can hold in their hand */
@ -59,13 +60,24 @@ typedef struct {
} pokerplayer_t; } pokerplayer_t;
/** /**
* Returns true if the player is still alive and in the current game/ * Returns whether or not the player is in the current round. This does not
* Defined as: Not out, not folded. * consider anything about whether they can/have bet or not, simply whether or
* not they can even partake in the round.
* *
* @param player Player to check * @param player
* @returns True if alive/in teh current game. * @return true
* @return false
*/ */
bool pokerPlayerIsAlive(pokerplayer_t *player); bool pokerPlayerIsInRound(pokerplayer_t *player);
/**
* Returns the count of players who remain in the current round. This is a sum
* of pokerPlayerIsInRound.
*
* @param players
* @return uint8_t
*/
uint8_t pokerPlayerGetCountInRound(pokerplayer_t *players);
/** /**
* Resets a poker player's state (for a new round). * Resets a poker player's state (for a new round).

View File

@ -6,3 +6,32 @@
*/ */
#include "poker.h" #include "poker.h"
void pokerGameWin(poker_t *poker) {
uint8_t i;
pokerplayerwinning_t *winning;
pokerplayer_t *player;
int32_t chipsRounded, chipsDifferent;
float chipsEach;
// 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;
}
}

View File

@ -50,4 +50,6 @@ typedef struct {
uint8_t roundBigBlind; uint8_t roundBigBlind;
uint8_t state; uint8_t state;
} poker_t; } poker_t;
void pokerGameWin(poker_t *poker);

View File

@ -336,7 +336,7 @@ void pokerWinnerCalculate(
left = winner->winnings + i; left = winner->winnings + i;
left->type = POKER_WINNING_TYPE_NULL; left->type = POKER_WINNING_TYPE_NULL;
player = players + i; player = players + i;
if(!pokerPlayerIsAlive(player)) continue; if(!pokerPlayerIsInRound(player)) continue;
// Get the players' winning state. // Get the players' winning state.
pokerWinnerPlayerGet(dealer, player, left); pokerWinnerPlayerGet(dealer, player, left);

View File

@ -123,4 +123,17 @@ void arraySplice(
// Now copy it back into the original array // Now copy it back into the original array
arrayCopy(size, temporary, takeLength, arrayGet(size, array, start)); arrayCopy(size, temporary, takeLength, arrayGet(size, array, start));
free(temporary); free(temporary);
}
int32_t arraySum(
size_t size, void *array, int32_t length, arraysumcallback_t *callback
) {
int32_t i, count;
count = 0;
for(i = 0; i < length; i++) {
if(!callback(arrayGet(size, array, i))) continue;
count++;
}
return count;
} }

View File

@ -18,6 +18,13 @@
*/ */
typedef int32_t arraysort_t(const void*, const void*); typedef int32_t arraysort_t(const void*, const void*);
/**
* Callback used when calculating the sum of an array that match a state.
* @param item Item within the array.
* @return True if counted, otherwise false.
*/
typedef bool arraysumcallback_t(void*);
/** /**
* Retreive the pointer to an elment within the array of unknown type. * Retreive the pointer to an elment within the array of unknown type.
* *
@ -149,4 +156,18 @@ void arrayRewind(size_t size, void *source, int32_t length, int32_t start,
*/ */
void arraySplice( void arraySplice(
size_t size, void *array, int32_t start, int32_t count, int32_t length size_t size, void *array, int32_t start, int32_t count, int32_t length
);
/**
* Sums the count of items that match a given filter in an array. The filter
* is a callback method that the user can define.
*
* @param size Size of each element within the array.
* @param array Array itself.
* @param length Length of the array.
* @param callback Callback that will return true/false when called.
* @return The count of items that matched the callback invokation.
*/
int32_t arraySum(
size_t size, void *array, int32_t length, arraysumcallback_t *callback
); );

View File

@ -73,4 +73,11 @@
* @param n Number to sign. * @param n Number to sign.
* @returns The signed number. * @returns The signed number.
*/ */
#define mathSign(n) (n>=0 ? 1.0f : -1.0f) #define mathSign(n) (n>=0 ? 1.0f : -1.0f)
/**
* Round a number down to the nearest whole number.
* @param n Floating number to round down.
* @returns The floor of the input.
*/
#define mathFloor(n) (floorf(n))

View File

@ -135,7 +135,6 @@ void vnSceneLookAt(vnscene_t *scene,
void vnSceneLookAtCharacter(vnscene_t *scene, uint8_t c, float distance) { void vnSceneLookAtCharacter(vnscene_t *scene, uint8_t c, float distance) {
vncharacter_t *character = scene->characters + c; vncharacter_t *character = scene->characters + c;
vnSceneLookAt(scene, vnSceneLookAt(scene,
-distance * sinf(character->yaw) + character->x, -distance * sinf(character->yaw) + character->x,
scene->cameraLook.y, scene->cameraLook.y,