From d4cc9075065f954585428aa224d052657b330fe8 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Mon, 27 Sep 2021 14:27:13 -0700 Subject: [PATCH] Fixed betting bugs. --- src/game/poker/actions/bet.c | 42 +++----------------------------- src/game/poker/actions/bet.h | 1 + src/game/poker/actions/flop.h | 25 +++++++++++++++++++ src/game/poker/actions/winner.c | 13 ++++++++++ src/game/poker/actions/winner.h | 1 + src/game/poker/pokerdiscussion.c | 2 ++ src/game/poker/pokergameaction.h | 1 + src/poker/actions/blinds.c | 2 -- src/poker/actions/deal.c | 2 +- src/poker/actions/round.c | 5 ++-- src/poker/bet.c | 13 +++++++--- src/poker/bet.h | 6 ++--- src/poker/dealer.c | 2 +- src/poker/player.c | 15 ++++++++++-- src/poker/player.h | 22 +++++++++++++---- src/poker/poker.c | 29 ++++++++++++++++++++++ src/poker/poker.h | 4 ++- src/poker/winner.c | 2 +- src/util/array.c | 13 ++++++++++ src/util/array.h | 21 ++++++++++++++++ src/util/math.h | 9 ++++++- src/vn/vnscene.c | 1 - 22 files changed, 169 insertions(+), 62 deletions(-) create mode 100644 src/game/poker/actions/flop.h diff --git a/src/game/poker/actions/bet.c b/src/game/poker/actions/bet.c index 637acb46..c5325165 100644 --- a/src/game/poker/actions/bet.c +++ b/src/game/poker/actions/bet.c @@ -86,11 +86,8 @@ void _pokerGameActionBetOnUpdate( void _pokerGameActionBetOnEnd( queue_t *queue, queueaction_t *action, uint8_t i ) { - queueaction_t *next; - pokerdiscussiondata_t discussion; pokergame_t *game = (pokergame_t *)action->data; - // Get which player is remaining to move. game->poker.bet.better = pokerBetGetRemainingPlayer( &game->poker.bet, game->poker.players, game->poker.roundSmallBlind @@ -101,47 +98,14 @@ void _pokerGameActionBetOnEnd( // Are we waiting on any players? if(game->poker.bet.better != 0xFF) { - if(game->poker.bet.better == POKER_PLAYER_HUMAN_INDEX) { - pokerGameActionLookAdd(game, POKER_DEALER_INDEX); - } else { - pokerGameActionLookAdd(game, game->poker.bet.better); - } + pokerGameActionLookAdd(game, game->poker.bet.better); pokerGameActionBetAdd(game); return; } - // Prep convo - discussion.poker = game; - - // Not waiting, restack and do next action. + // Not waiting, do next action. printf("Not waiting on anything!\n"); - - // 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); + pokerGameActionFlopAdd(game); } queueaction_t * pokerGameActionBetAdd(pokergame_t *game) { diff --git a/src/game/poker/actions/bet.h b/src/game/poker/actions/bet.h index 6dbbe97b..304c7af3 100644 --- a/src/game/poker/actions/bet.h +++ b/src/game/poker/actions/bet.h @@ -14,6 +14,7 @@ #include "action.h" #include "restack.h" #include "winner.h" +#include "flop.h" /** Callback when the bet action is updated. */ void _pokerGameActionBetOnUpdate( diff --git a/src/game/poker/actions/flop.h b/src/game/poker/actions/flop.h new file mode 100644 index 00000000..f203682e --- /dev/null +++ b/src/game/poker/actions/flop.h @@ -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); \ No newline at end of file diff --git a/src/game/poker/actions/winner.c b/src/game/poker/actions/winner.c index c98369ca..55b7dbf3 100644 --- a/src/game/poker/actions/winner.c +++ b/src/game/poker/actions/winner.c @@ -10,7 +10,10 @@ void _pokerGameActionWinnerOnStart( queue_t *queue, queueaction_t *action, uint8_t i ) { + pokerdiscussiondata_t discussion; pokergame_t *game = (pokergame_t *)action->data; + + // Calculate the winners printf("Winner start action"); pokerWinnerCalculate( &game->poker.winner, @@ -18,12 +21,22 @@ void _pokerGameActionWinnerOnStart( game->poker.players ); + // Action + pokerGameWin(&game->poker); + + // Debug printing. printf("Winner Count %u\n", game->poker.winner.winnerCount); for(uint8_t i = 0; i < game->poker.winner.winnerCount; i++) { uint8_t winner = game->poker.winner.winners[i]; printf("Winner %u\n", winner); } + // Say stuff + discussion.reason = POKER_DISCUSSION_REASON_BETTING_DONE; + discussion.poker = game; + pokerDiscussionQueue(&discussion); + + // Begin next round. pokerGameActionRoundAdd(game); queueNext(queue); } diff --git a/src/game/poker/actions/winner.h b/src/game/poker/actions/winner.h index 4d7827bf..431c2cf6 100644 --- a/src/game/poker/actions/winner.h +++ b/src/game/poker/actions/winner.h @@ -8,6 +8,7 @@ #pragma once #include "../../../libs.h" #include "../../../poker/winner.h" +#include "../../../poker/poker.h" #include "../pokerdiscussion.h" #include "action.h" #include "round.h" diff --git a/src/game/poker/pokerdiscussion.c b/src/game/poker/pokerdiscussion.c index 09a15437..77804a18 100644 --- a/src/game/poker/pokerdiscussion.c +++ b/src/game/poker/pokerdiscussion.c @@ -106,8 +106,10 @@ void pokerDiscussionQueue(pokerdiscussiondata_t *data) { pokerdiscussion_t discussion; uint8_t i, player; + // Fetch the discussion item for the given data. pokerDiscussionGet(&discussion, data); + // Now for each discussion item, queue a task. for(i = 0; i < discussion.count; i++) { player = discussion.players[i]; diff --git a/src/game/poker/pokergameaction.h b/src/game/poker/pokergameaction.h index f52af1d4..39d4c3c0 100644 --- a/src/game/poker/pokergameaction.h +++ b/src/game/poker/pokergameaction.h @@ -8,6 +8,7 @@ #pragma once #include "../../libs.h" +/** Representation of data that poker game actions can have access to. */ typedef struct { uint8_t lookAtPlayer; } pokergameactiondata_t; \ No newline at end of file diff --git a/src/poker/actions/blinds.c b/src/poker/actions/blinds.c index 3c15ecd5..c0751e58 100644 --- a/src/poker/actions/blinds.c +++ b/src/poker/actions/blinds.c @@ -10,9 +10,7 @@ void _pokerActionBlindsOnStart(queue_t *queue,queueaction_t *action,uint8_t i) { poker_t *poker; poker = (poker_t *)action->data; - poker->state = POKER_STATE_TAKING_BLINDS; - pokerBetTakeBlinds( &poker->bet, poker->players, diff --git a/src/poker/actions/deal.c b/src/poker/actions/deal.c index 0f91103c..e81f1119 100644 --- a/src/poker/actions/deal.c +++ b/src/poker/actions/deal.c @@ -11,9 +11,9 @@ void _pokerActionDealOnStart(queue_t *queue, queueaction_t *action, uint8_t i) { poker_t *poker; poker = (poker_t *)action->data; - poker->state = POKER_STATE_DEALING; // Shuffle the deck + poker->state = POKER_STATE_DEALING; cardShuffle(poker->dealer.deck, CARD_DECK_SIZE); // Deal 2 card to each player diff --git a/src/poker/actions/round.c b/src/poker/actions/round.c index 7c4d29af..723a9f3d 100644 --- a/src/poker/actions/round.c +++ b/src/poker/actions/round.c @@ -30,13 +30,14 @@ void _pokerActionRoundOnStart(queue_t *queue, queueaction_t *action ,uint8_t i){ // Decide on the dealer poker->roundDealer = (poker->roundDealer+1) % POKER_PLAYER_COUNT; - // Find the players. + // Find (and kill) the players. j = poker->roundDealer; foundDealer = false; foundSmallBlind = false; while(true) { player = poker->players + j; - if(!pokerPlayerIsAlive(player)) continue; + + if(!pokerPlayerIsInRound(player)) continue; if(!foundDealer) { indexDealer = j; foundDealer = true; diff --git a/src/poker/bet.c b/src/poker/bet.c index c2b0cae2..fe9ba160 100644 --- a/src/poker/bet.c +++ b/src/poker/bet.c @@ -42,10 +42,17 @@ void pokerBetResetBetter( } 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->currentBet >= bet->currentBet && player) return false; + if(player->currentBet >= bet->currentBet) return false; } + return true; } @@ -66,7 +73,7 @@ uint8_t pokerBetGetRemainingPlayerCount(pokerbet_t *bet,pokerplayer_t *players){ uint8_t i, c; c = 0; for(i = 0; i < POKER_PLAYER_COUNT; i++) { - if(!pokerPlayerIsAlive(players + i)) continue; + if(!pokerBetPlayerCanBet(bet, players + i)) continue; c++; } return c; diff --git a/src/poker/bet.h b/src/poker/bet.h index d2ce2758..cda4749d 100644 --- a/src/poker/bet.h +++ b/src/poker/bet.h @@ -7,6 +7,7 @@ #include "../libs.h" #include "player.h" #include "../util/math.h" +#include "../util/array.h" /** How many chips each player has by defautl */ #define POKER_BET_PLAYER_CHIPS_DEFAULT 10000 @@ -41,7 +42,7 @@ void pokerBetInit(pokerbet_t *bet); /** * Resets the bet state (for a new round). * - * @param bet + * @param bet Betting stating. */ 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 - * consider any round logic, simply whether or not they COULD bet. + * Returns the count of players who are still needing to bet. * * @param bet Betting instance * @param players Players array. diff --git a/src/poker/dealer.c b/src/poker/dealer.c index eea66cbd..29c5e0ac 100644 --- a/src/poker/dealer.c +++ b/src/poker/dealer.c @@ -48,7 +48,7 @@ void pokerDealerDealAll( for(y = 0; y < count; y++) { for(x = 0; x < POKER_PLAYER_COUNT; x++) { player = players + x; - if(!pokerPlayerIsAlive(player)) continue; + if(!pokerPlayerIsInRound(player)) continue; pokerDealerDeal(dealer, player); } } diff --git a/src/poker/player.c b/src/poker/player.c index 44593cbf..b797de48 100644 --- a/src/poker/player.c +++ b/src/poker/player.c @@ -7,8 +7,19 @@ #include "player.h" -bool pokerPlayerIsAlive(pokerplayer_t *player) { - return !(player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT)); +bool pokerPlayerIsInRound(pokerplayer_t *player) { + 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) { diff --git a/src/poker/player.h b/src/poker/player.h index 695ca595..b1ca26f6 100644 --- a/src/poker/player.h +++ b/src/poker/player.h @@ -8,6 +8,7 @@ #pragma once #include "../libs.h" #include "../util/flags.h" +#include "../util/array.h" #include "card.h" /** How many cards a player can hold in their hand */ @@ -59,13 +60,24 @@ typedef struct { } pokerplayer_t; /** - * Returns true if the player is still alive and in the current game/ - * Defined as: Not out, not folded. + * Returns whether or not the player is in the current round. This does not + * 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 - * @returns True if alive/in teh current game. + * @param player + * @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). diff --git a/src/poker/poker.c b/src/poker/poker.c index 6e1e0760..58a21756 100644 --- a/src/poker/poker.c +++ b/src/poker/poker.c @@ -6,3 +6,32 @@ */ #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; + } +} \ No newline at end of file diff --git a/src/poker/poker.h b/src/poker/poker.h index 76513bdc..6e71c785 100644 --- a/src/poker/poker.h +++ b/src/poker/poker.h @@ -50,4 +50,6 @@ typedef struct { uint8_t roundBigBlind; uint8_t state; -} poker_t; \ No newline at end of file +} poker_t; + +void pokerGameWin(poker_t *poker); \ No newline at end of file diff --git a/src/poker/winner.c b/src/poker/winner.c index b8cbac4a..2d2edbc0 100644 --- a/src/poker/winner.c +++ b/src/poker/winner.c @@ -336,7 +336,7 @@ void pokerWinnerCalculate( left = winner->winnings + i; left->type = POKER_WINNING_TYPE_NULL; player = players + i; - if(!pokerPlayerIsAlive(player)) continue; + if(!pokerPlayerIsInRound(player)) continue; // Get the players' winning state. pokerWinnerPlayerGet(dealer, player, left); diff --git a/src/util/array.c b/src/util/array.c index ad87d257..44ad30f3 100644 --- a/src/util/array.c +++ b/src/util/array.c @@ -123,4 +123,17 @@ void arraySplice( // Now copy it back into the original array arrayCopy(size, temporary, takeLength, arrayGet(size, array, start)); 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; } \ No newline at end of file diff --git a/src/util/array.h b/src/util/array.h index 9ead669c..59024e25 100644 --- a/src/util/array.h +++ b/src/util/array.h @@ -18,6 +18,13 @@ */ 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. * @@ -149,4 +156,18 @@ void arrayRewind(size_t size, void *source, int32_t length, int32_t start, */ void arraySplice( 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 ); \ No newline at end of file diff --git a/src/util/math.h b/src/util/math.h index 1fcf59a6..919359e1 100644 --- a/src/util/math.h +++ b/src/util/math.h @@ -73,4 +73,11 @@ * @param n Number to sign. * @returns The signed number. */ -#define mathSign(n) (n>=0 ? 1.0f : -1.0f) \ No newline at end of file +#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)) \ No newline at end of file diff --git a/src/vn/vnscene.c b/src/vn/vnscene.c index 02e7330b..780002e7 100644 --- a/src/vn/vnscene.c +++ b/src/vn/vnscene.c @@ -135,7 +135,6 @@ void vnSceneLookAt(vnscene_t *scene, void vnSceneLookAtCharacter(vnscene_t *scene, uint8_t c, float distance) { vncharacter_t *character = scene->characters + c; - vnSceneLookAt(scene, -distance * sinf(character->yaw) + character->x, scene->cameraLook.y,