From cc9e50c4ab3d843143e5f50c284e8c6951b89860 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sun, 9 Jan 2022 20:15:16 -0800 Subject: [PATCH] Working on the poker game stuff. --- assets/strings.js | 11 ++- src/conversation/queue.c | 180 ++++++++++++++++++++++++++++++++++++--- src/conversation/queue.h | 17 +++- src/main.c | 1 + src/poker/poker.c | 31 +++++-- src/poker/poker.h | 13 +-- src/poker/pot.h | 43 ++++++++++ 7 files changed, 265 insertions(+), 31 deletions(-) create mode 100644 src/poker/pot.h diff --git a/assets/strings.js b/assets/strings.js index d6d773a..19c9912 100644 --- a/assets/strings.js +++ b/assets/strings.js @@ -1,8 +1,17 @@ const GAME_STRINGS = { + 'ERROR': 'An error\nhas occured', 'HELLO': 'Hello World!\nHow are you today?\nThank god!', 'POKER_GAME_START': 'Poker game started', - 'POKER_GAME_TAKING_BLINDS': 'Blinds taken.' + 'POKER_GAME_TAKING_BLINDS': 'Blinds taken.', + 'POKER_GAME_CARDS_DEALT': 'Cards dealt.', + + 'POKER_GAME_CARDS_FLOPPED': 'Cards flopped', + 'POKER_GAME_CARDS_TURNED': 'Cards turned', + 'POKER_GAME_CARDS_RIVERED': 'Cards river', + + 'DEBUG_WINNER_DECIDED': 'DEBUG WINNER', + 'BURNOUT': 'Burnout gey\nlmao.' }; module.exports = { GAME_STRINGS }; \ No newline at end of file diff --git a/src/conversation/queue.c b/src/conversation/queue.c index 0aa2a80..f6eba8f 100644 --- a/src/conversation/queue.c +++ b/src/conversation/queue.c @@ -13,23 +13,179 @@ uint16_t QUEUE_ITEM; -void conversationQueueInit() { - QUEUE_ITEM = QUEUE_BEGIN; +void conversationQueueDebug() { + conversationTextboxString(ERROR); } -void conversationQueueNext() { - BGB_printf("Queue item: %d\n", QUEUE_ITEM); +void conversationQueueBegin() { + QUEUE_ITEM = QUEUE_TAKE_BLINDS; + conversationTextboxString(POKER_GAME_START); +} - switch(QUEUE_ITEM) { - case QUEUE_BEGIN: - conversationTextboxString(POKER_GAME_START); - QUEUE_ITEM = QUEUE_TAKE_BLINDS; +void conversationQueueTakeBlinds() { + QUEUE_ITEM = QUEUE_DEAL_CARDS; + conversationTextboxString(POKER_GAME_TAKING_BLINDS); +} + +void conversationQueueDealCards() { + QUEUE_ITEM = QUEUE_BEGIN_BETTING; + conversationTextboxString(POKER_GAME_CARDS_DEALT); +} + +void conversationQueueBeginBetting() { + uint8_t i; + // Begin the betting process. First we need to decide if the player or the + // AI is betting, then based on that we decide what to do next. + + // TODO: Next better + if(POKER_PLAYER_BETTER == POKER_HUMAN_INDEX) { + // This is the human player. + BGB_MESSAGE("Players turn to bet"); + POKER_PLAYERS[ + POKER_PLAYER_BETTER + ].state |= POKER_PLAYER_STATE_HAS_BET_THIS_ROUND; + } else { + // This is an AI player. + BGB_MESSAGE("AI turn to bet"); + POKER_PLAYERS[ + POKER_PLAYER_BETTER + ].state |= POKER_PLAYER_STATE_HAS_BET_THIS_ROUND; + } + // TODO: Decide if we need to continue betting or decide a winner + for(i = 0; i < POKER_PLAYER_COUNT_MAX; i++) { + // Can the player even do anything? + if( + ( + POKER_PLAYERS[POKER_PLAYER_BETTER].state & + (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT) + ) != 0 || + POKER_PLAYERS[POKER_PLAYER_BETTER].chips == 0 + ) continue; + + // Has the player bet? If so are they in the current pot? + if(( + POKER_PLAYERS[POKER_PLAYER_BETTER].state & + POKER_PLAYER_STATE_HAS_BET_THIS_ROUND + ) != 0) { + // TODO: confirm uh if they are up to the currently raised pot point or + // not. + continue; + } + + // They haven't bet yet, make them the "next better" + } + + // If we reach this point then we either need to begin the betting round, or + // we are going to move to the winning decider. TODO: Figure out if winning + // phase or turn phase. + + QUEUE_ITEM = QUEUE_FLOP; + conversationQueueNext(); +} + +void conversationQueueFlopTurnRiver() { + uint8_t i, count; + + QUEUE_ITEM = QUEUE_BEGIN_BETTING; + + switch(POKER_COMMUNITY_SIZE) { + case 0: + count = POKER_COUNT_FLOP; + conversationTextboxString(POKER_GAME_CARDS_FLOPPED); break; - case QUEUE_TAKE_BLINDS: - pokerTakeBlinds(); - conversationTextboxString(POKER_GAME_TAKING_BLINDS); - QUEUE_ITEM = QUEUE_TAKE_BLINDS; + case POKER_COUNT_FLOP: + count = POKER_COUNT_TURN; + conversationTextboxString(POKER_GAME_CARDS_TURNED); + break; + + default: + count = POKER_COUNT_RIVER; + conversationTextboxString(POKER_GAME_CARDS_RIVERED); break; } + + // In reality we'd burn the top card but that would waste some CPU I need. + // Deal the top cards. + for(i = 0; i < count; i++) { + POKER_COMMUNITY[POKER_COMMUNITY_SIZE++] = POKER_DECK[POKER_DECK_SIZE--]; + } +} + +void conversationQueueWinnerDecide() { + QUEUE_ITEM = QUEUE_DEBUG; + + // TODO: Decide on a winner for real. + conversationTextboxString(DEBUG_WINNER_DECIDED); +} + +//////////////////////////////////////////////////////////////////////////////// + +queuecallback_t *QUEUE_CALLBACKS[] = { + // 0 + NULL, + &conversationQueueDebug, + NULL, + NULL, + NULL, + + // 5 + &conversationQueueBegin, + NULL, + NULL, + NULL, + NULL, + + // 10 + &conversationQueueTakeBlinds, + NULL, + NULL, + NULL, + NULL, + + // 15 + &conversationQueueDealCards, + NULL, + NULL, + NULL, + NULL, + + // 20 + &conversationQueueBeginBetting, + NULL, + NULL, + NULL, + NULL, + + // 25 + &conversationQueueFlopTurnRiver, + NULL, + NULL, + NULL, + NULL, + + // 30 + NULL, + NULL, + NULL, + NULL, + NULL, + + // 35 + NULL, + NULL, + NULL, + NULL, + NULL, + + // 40 + &conversationQueueWinnerDecide, + // NULL, + // NULL, + // NULL, + // NULL, +}; + +void conversationQueueInit() { + QUEUE_ITEM = QUEUE_BEGIN; } \ No newline at end of file diff --git a/src/conversation/queue.h b/src/conversation/queue.h index 391c039..ac5c9aa 100644 --- a/src/conversation/queue.h +++ b/src/conversation/queue.h @@ -9,10 +9,19 @@ #include "../libs.h" #include "STRINGS.h" +typedef void queuecallback_t(); + extern uint16_t QUEUE_ITEM; +extern queuecallback_t *QUEUE_CALLBACKS[]; -#define QUEUE_BEGIN 10 -#define QUEUE_TAKE_BLINDS 20 +#define QUEUE_DEBUG 1 +#define QUEUE_BEGIN 5 +#define QUEUE_TAKE_BLINDS 10 +#define QUEUE_DEAL_CARDS 15 +#define QUEUE_BEGIN_BETTING 20 +#define QUEUE_FLOP 25 +#define QUEUE_WINNER_DECIDE 40 -void conversationQueueInit(); -void conversationQueueNext(); \ No newline at end of file +#define conversationQueueNext() QUEUE_CALLBACKS[QUEUE_ITEM]() + +void conversationQueueInit(); \ No newline at end of file diff --git a/src/main.c b/src/main.c index e4d16ed..4c30c0e 100644 --- a/src/main.c +++ b/src/main.c @@ -49,6 +49,7 @@ void main() { wait_vbl_done(); // Alright begin the game logic here. + BGB_MESSAGE("Begin."); conversationQueueNext(); // Begin the loop diff --git a/src/poker/poker.c b/src/poker/poker.c index c0a0a95..83a6624 100644 --- a/src/poker/poker.c +++ b/src/poker/poker.c @@ -8,18 +8,22 @@ #include "poker.h" pokerplayer_t POKER_PLAYERS[POKER_PLAYER_COUNT_MAX]; + uint8_t POKER_DECK[CARD_DECK_SIZE]; uint8_t POKER_DECK_SIZE; - uint8_t POKER_COMMUNITY[POKER_COMMUNITY_SIZE_MAX]; uint8_t POKER_COMMUNITY_SIZE; uint8_t POKER_PLAYER_DEALER; uint8_t POKER_PLAYER_SMALL_BLIND; uint8_t POKER_PLAYER_BIG_BLIND; +uint8_t POKER_PLAYER_BETTER; uint16_t POKER_GAME_BLINDS_CURRENT; -uint16_t POKER_GAME_POT; + +pokerpot_t POKER_POTS[POKER_POT_COUNT_MAX]; +uint8_t POKER_POT_CURRENT; +uint8_t POKER_POT_COUNT; void pokerInit() { uint8_t i; @@ -33,8 +37,6 @@ void pokerInit() { // Set up the initial state. // TODO: Should this be randomized? POKER_PLAYER_DEALER = 0; - POKER_GAME_POT = 0; - POKER_GAME_BLINDS_CURRENT = 10; // Reset the round state (For the first round) @@ -47,6 +49,15 @@ void pokerNewRound() { // Reset round state POKER_COMMUNITY_SIZE = 0; + POKER_POT_COUNT = 0; + POKER_POT_CURRENT = 0; + + // Reset the pots. + for(i = 0; i < POKER_POT_COUNT_MAX; i++) { + POKER_POTS[i].chips = 0; + POKER_POTS[i].call = 0; + POKER_POTS[i].playersCount = 0; + } // Fill deck for(i = 0; i < CARD_DECK_SIZE; i++) POKER_DECK[i] = i; @@ -91,11 +102,13 @@ void pokerNewRound() { POKER_PLAYERS[i].hand[j] = POKER_DECK[POKER_DECK_SIZE--]; } } -} -void pokerTakeBlinds() { + // Take blinds // TODO: I need to make sure the blind players even have the chips to blind. - POKER_PLAYERS[POKER_PLAYER_SMALL_BLIND].chips -= POKER_GAME_BLINDS_CURRENT; - POKER_PLAYERS[POKER_PLAYER_BIG_BLIND].chips -= (POKER_GAME_BLINDS_CURRENT*2); - POKER_GAME_POT += POKER_GAME_BLINDS_CURRENT * 3; + POKER_POT_BET(POKER_PLAYER_SMALL_BLIND, POKER_GAME_BLINDS_CURRENT); + POKER_POT_BET(POKER_PLAYER_BIG_BLIND, (POKER_GAME_BLINDS_CURRENT*2)); + + // Set the initial better, we set this to the BIG BLIND player because we will + // cycle to the "next better" as soon as the game starts. + POKER_PLAYER_BETTER = POKER_PLAYER_BIG_BLIND; } \ No newline at end of file diff --git a/src/poker/poker.h b/src/poker/poker.h index 9253b12..7044a87 100644 --- a/src/poker/poker.h +++ b/src/poker/poker.h @@ -9,24 +9,27 @@ #include "../libs.h" #include "card.h" #include "player.h" +#include "pot.h" #define POKER_COMMUNITY_SIZE_MAX 5 +#define POKER_HUMAN_INDEX 0x00 + +#define POKER_COUNT_FLOP 0x03 +#define POKER_COUNT_TURN 0x01 +#define POKER_COUNT_RIVER 0x01 extern uint8_t POKER_DECK[]; extern uint8_t POKER_DECK_SIZE; - extern uint8_t POKER_COMMUNITY[]; extern uint8_t POKER_COMMUNITY_SIZE; extern uint8_t POKER_PLAYER_DEALER; extern uint8_t POKER_PLAYER_SMALL_BLIND; extern uint8_t POKER_PLAYER_BIG_BLIND; +extern uint8_t POKER_PLAYER_BETTER; extern uint16_t POKER_GAME_BLINDS_CURRENT; -extern uint16_t POKER_GAME_POT; void pokerInit(); -void pokerNewRound(); - -void pokerTakeBlinds(); \ No newline at end of file +void pokerNewRound(); \ No newline at end of file diff --git a/src/poker/pot.h b/src/poker/pot.h new file mode 100644 index 0000000..83e958a --- /dev/null +++ b/src/poker/pot.h @@ -0,0 +1,43 @@ +/** + * Copyright (c) 2022 Dominic Masters + * + * This software is released under the MIT License. + * https://opensource.org/licenses/MIT + */ + +#pragma once +#include "../libs.h" +#include "player.h" + +#define POKER_POT_COUNT_MAX POKER_PLAYER_COUNT_MAX + +typedef struct { + /** Current pot of chips */ + uint16_t chips; + + /** Current call value for this pot */ + uint16_t call; + + /** Players who are participating in the pot */ + uint8_t players[POKER_PLAYER_COUNT_MAX]; + uint8_t playersCount; +} pokerpot_t; + +extern pokerpot_t POKER_POTS[]; +extern uint8_t POKER_POT_CURRENT; +extern uint8_t POKER_POT_COUNT; + + +// TODO: This may become a function because if a player doesn't have enough +// chips to bet to the active pot, then the pot needs to autosplit, take those +// who have bet into the pot up to the amount that the player betting can bet, +// and push them into a new pot. +// There also needs to be a limit on this, for example; +// player 0 has $1200, and bets $1000, he can't bet more than that ever. +// player 1 has $1000, and bets all of it. The remanin +// player 2 has $700, and bets all o it. A new $300 sidepot auto creates +// player 3 has $500 and bets all of it, Another sidepot with $200 is auto made. +#define POKER_POT_BET(player, amount) \ + POKER_PLAYERS[player].chips -= amount;\ + POKER_POTS[POKER_POT_CURRENT].chips += amount;\ + POKER_POTS[POKER_POT_CURRENT].call = amount; \ No newline at end of file