diff --git a/backup/poker/bet.c b/backup/poker/bet.c deleted file mode 100644 index d820b407..00000000 --- a/backup/poker/bet.c +++ /dev/null @@ -1,105 +0,0 @@ -/** - * Copyright (c) 2021 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "bet.h" - -// Done -void pokerBetInit(pokerbet_t *bet) { - bet->blindBig = POKER_BET_BLIND_BIG_DEFAULT; - bet->blindSmall = POKER_BET_BLIND_SMALL_DEFAULT; -} - -// Done -void pokerBetReset(pokerbet_t *bet) { - bet->pot = 0; - bet->currentBet = 0; -} - -// Not needed -uint8_t pokerBetGetRoundPlayerDefault(uint8_t roundSmallBlind) { - return (roundSmallBlind + 1) % POKER_PLAYER_COUNT; -} - -// Done -void pokerBetPlayer(pokerbet_t *bet, pokerplayer_t *player, int32_t chips) { - bet->pot += chips; - player->chips -= chips; - player->currentBet += chips; - bet->currentBet = mathMax(bet->currentBet, player->currentBet); -} - -// Doneish -void pokerBetResetBetter( - pokerbet_t *bet, pokerplayer_t *players, uint8_t roundSmallBlind -) { - uint8_t i; - pokerplayer_t *player; - - // Reset the round betting state. - for(i = 0; i < POKER_PLAYER_COUNT; i++) { - player = players + i; - player->state = flagOff(player->state, POKER_PLAYER_STATE_ROUND_MOVE); - } - - // Now reset to the first player that needs to bet. - - // We do this step first to reset the better - bet->better = pokerBetGetRoundPlayerDefault(roundSmallBlind); - - // Then we check who's remaining. We do this because the default better may - // have folded already. - bet->better = pokerBetGetRemainingPlayer(bet, players, roundSmallBlind); -} - -// Doneish -bool pokerBetPlayerCanBet(pokerbet_t *bet, pokerplayer_t *player) { - // 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) return false; - } - - return true; -} - -uint8_t pokerBetGetRemainingPlayer( - pokerbet_t *bet, pokerplayer_t *players, uint8_t roundSmallBlind -) { - uint8_t def, j, pi; - def = bet->better; - - // Now check for any remaining players - for(j = 0; j < POKER_PLAYER_COUNT; j++) { - pi = ((def + j) % POKER_PLAYER_COUNT); - if(!pokerBetPlayerCanBet(bet, players + pi)) continue; - return pi; - } - return 0xFF; -} - -uint8_t pokerBetGetRemainingPlayerCount(pokerbet_t *bet,pokerplayer_t *players){ - uint8_t i, c; - c = 0; - for(i = 0; i < POKER_PLAYER_COUNT; i++) { - if(!pokerBetPlayerCanBet(bet, players + i)) continue; - c++; - } - return c; -} - -void pokerBetTakeBlinds( - pokerbet_t *bet, pokerplayer_t *players, - uint8_t roundSmallBlind, uint8_t roundBigBlind -) { - pokerBetPlayer(bet, players + roundSmallBlind, bet->blindSmall); - pokerBetPlayer(bet, players + roundBigBlind, bet->blindBig); -} \ No newline at end of file diff --git a/backup/poker/bet.h b/backup/poker/bet.h deleted file mode 100644 index ce29d5ec..00000000 --- a/backup/poker/bet.h +++ /dev/null @@ -1,117 +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 "player.h" -#include "../util/math.h" -#include "../util/array.h" - -/** 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 { - /** Blinds */ - int32_t blindSmall, blindBig; - - /** How big the current bet is for the round. */ - int32_t currentBet; - - /** For Betting round, which player is currently betting */ - uint8_t better; - - /** Current pot of chips */ - int32_t pot; -} pokerbet_t; - -/** - * Initializes/resets the poker bet context. - * - * @param bet Poker bet instance. - */ -void pokerBetInit(pokerbet_t *bet); - -/** - * Resets the bet state (for a new round). - * - * @param bet Betting stating. - */ -void pokerBetReset(pokerbet_t *bet); - -/** - * The default betting player for the round. - * - * @param roundSmallBlind Current round small blind player index. - * @return The Poker round default betting player index. - */ -uint8_t pokerBetGetRoundPlayerDefault(uint8_t roundSmallBlind); - -/** - * Let a player bet chips into the pot. - * - * @param bet Poker bet instance. - * @param player Poker player instance. - * @param chips Chips to bet. - */ -void pokerBetPlayer(pokerbet_t *bet, pokerplayer_t *player, int32_t chips); - -/** - * Reset the current better back to the round/turns default. The better will - * always be the player to the right of the small blind player. - * - * @param bet Poker betting structure. - * @param player Array of poker players. - * @param roundSmallBlind Current round small blind player index. - */ -void pokerBetResetBetter( - pokerbet_t *poker, pokerplayer_t *players, uint8_t roundSmallBlind -); - -/** - * Returns whether or not a player can bet for the current round. - * - * @param bet Game bet state. - * @param player Player to check. - * @return True if the player can bet, otherwise false. - */ -bool pokerBetPlayerCanBet(pokerbet_t *bet, pokerplayer_t *player); - -/** - * Returns the index of the first player that remains to bet for the current - * round. - * - * @param bet Poker betting structure. - * @param player Array of poker players. - * @param roundSmallBlind Current round small blind player index. - * @return The player index of the remaining player, otherwise 0xFF. - */ -uint8_t pokerBetGetRemainingPlayer( - pokerbet_t *bet, pokerplayer_t *players, uint8_t roundSmallBlind -); - -/** - * Returns the count of players who are still needing to bet. - * - * @param bet Betting instance - * @param players Players array. - * @return Count of players who can still bet. - */ -uint8_t pokerBetGetRemainingPlayerCount(pokerbet_t *bet,pokerplayer_t *players); - -/** - * Takes the current blinds from the correct players. - * - * @param poker Poker game to take the blinds from. - */ -void pokerBetTakeBlinds( - pokerbet_t *bet, pokerplayer_t *players, - uint8_t roundSmallBlind, uint8_t roundBigBlind -); \ No newline at end of file diff --git a/backup/poker/dealer.c b/backup/poker/dealer.c deleted file mode 100644 index 7bb24c0c..00000000 --- a/backup/poker/dealer.c +++ /dev/null @@ -1,60 +0,0 @@ -/** - * Copyright (c) 2021 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ -#include "dealer.h" - -//Not needed -void pokerDealerInit(pokerdealer_t *dealer) { - uint8_t i; - - dealer->graveSize = 0; - dealer->cardsFacing = 0; - dealer->deckSize = CARD_DECK_SIZE; - for(i = 0; i < CARD_DECK_SIZE; i++) dealer->deck[i] = i; -} - -// Done -void pokerDealerTurn(pokerdealer_t *dealer, uint8_t count) { - uint8_t i; - for(i = 0; i < count; i++) { - cardDeal( - dealer->deck, &dealer->deckSize, - dealer->cards, &dealer->cardsFacing - ); - } -} - -// Done -void pokerDealerBurn(pokerdealer_t *dealer, uint8_t count) { - uint8_t i; - for(i = 0; i < count; i++) { - cardDeal( - dealer->deck, &dealer->deckSize, - dealer->grave, &dealer->graveSize - ); - } -} - -// Done -void pokerDealerDeal(pokerdealer_t *dealer, pokerplayer_t *player) { - cardDeal(dealer->deck, &dealer->deckSize, player->cards, &player->cardCount); -} - -// Done -void pokerDealerDealAll( - pokerdealer_t *dealer, pokerplayer_t *players, uint8_t count -) { - uint8_t x, y; - pokerplayer_t *player; - - for(y = 0; y < count; y++) { - for(x = 0; x < POKER_PLAYER_COUNT; x++) { - player = players + x; - if(!pokerPlayerIsInRound(player)) continue; - pokerDealerDeal(dealer, player); - } - } -} \ No newline at end of file diff --git a/backup/poker/dealer.h b/backup/poker/dealer.h deleted file mode 100644 index 3330d1f3..00000000 --- a/backup/poker/dealer.h +++ /dev/null @@ -1,76 +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 "card.h" -#include "player.h" - -/** How many cards the dealer can hold in their hand */ -#define POKER_DEALER_HAND_SIZE 5 - -/** How many cards the grave can hold */ -#define POKER_DEALER_GRAVE_SIZE CARD_DECK_SIZE - -/** Which VN Character index is the dealer */ -#define POKER_DEALER_INDEX POKER_PLAYER_HUMAN_INDEX - -/** Representation of the dealer state */ -typedef struct { - /** Current Card Deck */ - card_t deck[CARD_DECK_SIZE]; - uint8_t deckSize; - - /** Dealer Hand */ - card_t cards[POKER_DEALER_HAND_SIZE]; - uint8_t cardsFacing; - - /** Card grave (where spent cards go when burned */ - card_t grave[POKER_DEALER_GRAVE_SIZE]; - uint8_t graveSize; -} pokerdealer_t; - -/** - * Initializes/Resets a dealer state. - * - * @param dealer Dealer's state to reset. - */ -void pokerDealerInit(pokerdealer_t *dealer); - -/** - * Turns over cards from the deck onto the table (from the deck into the dealer - * hand) - * - * @param dealer Poker dealer instance. - * @param count Count of cards to deal. - */ -void pokerDealerTurn(pokerdealer_t *dealer, uint8_t count); - -/** - * Burns a set of cards off the top of the deck into the graveyard. - * - * @param dealer Poker dealer instance. - * @param count Count of cards to burn. - */ -void pokerDealerBurn(pokerdealer_t *dealer, uint8_t count); - -/** - * Deal a card to a player. - * - * @param dealer Poker dealer instance. - * @param player Poker player to deal to. - */ -void pokerDealerDeal(pokerdealer_t *dealer, pokerplayer_t *player); - -/** - * Deal card(s) to every active player. - * - * @param dealer Poker dealer instance. - * @param players Array of poker players. - * @param count Count of cards to deal. - */ -void pokerDealerDealAll( - pokerdealer_t *dealer, pokerplayer_t *players, uint8_t count -); \ No newline at end of file diff --git a/backup/poker/player.c b/backup/poker/player.c deleted file mode 100644 index b797de48..00000000 --- a/backup/poker/player.c +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright (c) 2021 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "player.h" - -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) { - player->cardCount = 0; - player->currentBet = 0; - player->timesRaised = 0; - - // Invert then bitwise AND to turn off. - player->state &= ~( - POKER_PLAYER_STATE_FOLDED | - POKER_PLAYER_STATE_SHOWING - ); -} \ No newline at end of file diff --git a/backup/poker/player.h b/backup/poker/player.h deleted file mode 100644 index b1ca26f6..00000000 --- a/backup/poker/player.h +++ /dev/null @@ -1,87 +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 "card.h" - -/** How many cards a player can hold in their hand */ -#define POKER_PLAYER_HAND 2 - -/** How many players in a poker game (excludes dealer) */ -#define POKER_PLAYER_COUNT 5 - - -//////////////////////////////////////////////////////////////////////////////// -// Player States -//////////////////////////////////////////////////////////////////////////////// -/** State for whether or not a player has folded */ -#define POKER_PLAYER_STATE_FOLDED flagDefine(0) - -/** State for whether or not a player is showing their hand */ -#define POKER_PLAYER_STATE_SHOWING flagDefine(1) - -/** State for whether or not the player is out */ -#define POKER_PLAYER_STATE_OUT flagDefine(2) - -/** Flag that is reset at the start of each round, and set when move occurs. */ -#define POKER_PLAYER_STATE_ROUND_MOVE flagDefine(3) - -/** The index that the player who is the human... is */ -#define POKER_PLAYER_HUMAN_INDEX 0x02 - -//////////////////////////////////////////////////////////////////////////////// -// Player Definition -//////////////////////////////////////////////////////////////////////////////// - -/** Poker Player State */ -typedef struct { - /** Cards in the players' hand */ - card_t cards[POKER_PLAYER_HAND]; - uint8_t cardCount; - - /** Current State of player */ - uint8_t state; - - /** Chips in players' posession */ - int32_t chips; - - /** Current bet in current round player has placed */ - int32_t currentBet; - - /** How many times for the current flop that the player has raised */ - int32_t timesRaised; -} pokerplayer_t; - -/** - * 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 - * @return true - * @return false - */ -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). - * - * @param player Player to reset. - */ -void pokerPlayerReset(pokerplayer_t *player); \ No newline at end of file diff --git a/backup/poker/poker.c b/backup/poker/poker.c deleted file mode 100644 index 3c7b322c..00000000 --- a/backup/poker/poker.c +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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; - } -} \ No newline at end of file diff --git a/backup/poker/poker.h b/backup/poker/poker.h deleted file mode 100644 index aab60377..00000000 --- a/backup/poker/poker.h +++ /dev/null @@ -1,60 +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 "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); \ No newline at end of file diff --git a/backup/poker/turn.c b/backup/poker/turn.c deleted file mode 100644 index 25c10ec6..00000000 --- a/backup/poker/turn.c +++ /dev/null @@ -1,237 +0,0 @@ -/** - * Copyright (c) 2021 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "turn.h" - -pokerturn_t pokerTurnGet(poker_t *poker, uint8_t playerIndex) { - int32_t random, maxBet, bluffBet, callBet; - float confidence, expectedGain, potOdds; - bool isBluff; - int32_t amount; - pokerplayer_t *player; - pokerplayerwinning_t winning; - uint8_t i, cardNumber0, cardNumber1, suitNumber0, suitNumber1; - pokerturn_t turn; - - player = poker->players + playerIndex; - - // Can the player do anything? - if(player->state & (POKER_PLAYER_STATE_FOLDED | POKER_PLAYER_STATE_OUT)) { - return pokerTurnOut(poker, playerIndex); - } - - // The following logic is heavily inspired by; - // https://github.com/gorel/C-Poker-AI/blob/master/src/common/pokerai.c - // But with some changes and smarts added by me. The original source code will - // essentially just run a crap tun of simulated games and get the times that - // they are expected to win from those games, but I'm just going to use the - // odds of the winning hand. - - // Is this preflop? - if(poker->dealer.cardsFacing == 0 && player->cardCount >= 2) { - // Get the hand weight - cardNumber0 = cardGetNumber(player->cards[0]); - cardNumber1 = cardGetNumber(player->cards[1]); - suitNumber0 = cardGetSuit(player->cards[0]); - suitNumber1 = cardGetSuit(player->cards[1]); - - // Get delta between cards - i = mathAbs(cardNumber0 - cardNumber1); - - // Get card weight - confidence = (float)cardNumber0 + (float)cardNumber1; - if(cardNumber0 == cardNumber1) {// Pairs - confidence += 6; - } else if(suitNumber0 == suitNumber1) {// Same suit - confidence += 4; - } - - // Get difference from cards for guessing flush - if(i > 4) { - confidence -= 4; - } else if(i > 2) { - confidence -= i; - } - - // Get the confidence delta 0-1 - confidence = confidence / 30.0f; - } else { - // Simulate my hand being the winning hand, use that as the confidence - pokerWinnerPlayerGet(&poker->dealer, player, &winning); - confidence = pokerWinnerGetTypeConfidence(winning.type); - } - - // Now we know how confident the AI is, let's put a chip value to that weight - // How many chips to call? - callBet = poker->bet.currentBet - player->currentBet; - - // Do they need chips to call, or is it possible to check? - if(callBet > 0) { - potOdds = (float)callBet / ((float)callBet + (float)poker->bet.pot); - } else { - potOdds = ( - 1.0f / (float)pokerBetGetRemainingPlayerCount(&poker->bet, poker->players) - ); - } - - // Now determine the expected ROI - expectedGain = confidence / potOdds; - - // Now get a random 0-100 - random = randInt32() % 100; - - // Determine the max bet that the AI is willing to make - maxBet = (int32_t)((float)player->chips / 1.75f) - (random / 2); - maxBet -= callBet; - - // Determine what's a good bluff bet. - bluffBet = random * maxBet / 100 / 2; - - // Now prep the output - isBluff = false; - amount = 0; - - // Now the actual AI can happen. This is basically a weight to confidence - // ratio. The higher the gains and the confidence then the more likely the AI - // is to betting. There are also bluff chances within here. - if(expectedGain < 0.8 && confidence < 0.8) { - if(random < 95) { - amount = 0; - } else { - amount = bluffBet; - isBluff = true; - } - } else if ((expectedGain < 1.0 && confidence < 0.85) || confidence < 0.1) { - if (random < 80) { - amount = 0; - } else if(random < 5) { - amount = callBet; - isBluff = true; - } else { - amount = bluffBet; - isBluff = true; - } - } else if ((expectedGain < 1.3 && confidence < 0.9) || confidence < 0.5) { - if (random < 60 || confidence < 0.5) { - amount = callBet; - } else { - amount = maxBet; - } - } else if (confidence < 0.95 || poker->dealer.cardsFacing < 0x04) { - if(random < 20) { - amount = callBet; - } else { - amount = maxBet; - } - } else { - amount = (player->chips - callBet) * 9 / 10; - } - - // If this is the first round... make it a lot less likely I'll bet - if(poker->dealer.cardsFacing == 0x00 && amount > callBet) { - if(random > 5) amount = callBet; - } - - // Did we actually bet? - if(amount > 0) { - printf("AI is betting %i chips, bluff: %i\n", amount, isBluff); - - // Let's not get caught in a raising loop with AI. - if(player->timesRaised >= POKER_TURN_MAX_RAISES) { - amount = callBet; - } - - amount = mathMax(amount, callBet); - turn = pokerTurnRaise(poker, playerIndex, amount); - turn.confidence = confidence; - } else if(pokerTurnCanPlayerCheck(poker, playerIndex)) { - turn = pokerTurnCheck(poker, playerIndex); - turn.confidence = 1; - } else { - turn = pokerTurnFold(poker, playerIndex); - turn.confidence = 1 - confidence; - } - - - return turn; -} - -void pokerTurnAction(poker_t *poker, pokerplayer_t *player, pokerturn_t *turn) { - switch(turn->type) { - case POKER_TURN_TYPE_BET: - case POKER_TURN_TYPE_CALL: - case POKER_TURN_TYPE_ALL_IN: - pokerBetPlayer(&poker->bet, player, turn->chips); - player->timesRaised++; - break; - - case POKER_TURN_TYPE_CHECK: - pokerBetPlayer(&poker->bet, player, 0); - player->timesRaised = 0; - break; - - case POKER_TURN_TYPE_FOLD: - player->state |= POKER_PLAYER_STATE_FOLDED; - player->timesRaised = 0; - break; - } - - player->state |= POKER_PLAYER_STATE_ROUND_MOVE; -} - -pokerturn_t pokerTurnOut(poker_t *poker, uint8_t player) { - pokerturn_t turn; - turn.type = POKER_TURN_TYPE_OUT; - return turn; -} - -pokerturn_t pokerTurnFold(poker_t *poker, uint8_t player) { - pokerturn_t turn; - turn.type = POKER_TURN_TYPE_FOLD; - return turn; -} - -pokerturn_t pokerTurnCheck(poker_t *poker, uint8_t player) { - return pokerTurnRaise(poker, player, 0); -} - -pokerturn_t pokerTurnCall(poker_t *poker, uint8_t playerIndex) { - pokerturn_t turn; - pokerplayer_t *player; - player = poker->players + playerIndex; - turn = pokerTurnRaise( - poker, playerIndex, poker->bet.currentBet - player->currentBet - ); - return turn; -} - -pokerturn_t pokerTurnRaise(poker_t *poker, uint8_t playerIndex, int32_t chips) { - pokerturn_t turn; - pokerplayer_t *player; - player = poker->players + playerIndex; - - 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; - - if(chips == (poker->bet.currentBet - player->currentBet)) { - turn.type = POKER_TURN_TYPE_CALL; - } - } - - return turn; -} - -bool pokerTurnCanPlayerCheck(poker_t *poker, uint8_t playerIndex) { - return (poker->players + playerIndex)->currentBet >= poker->bet.currentBet; -} \ No newline at end of file diff --git a/backup/poker/turn.h b/backup/poker/turn.h deleted file mode 100644 index d083c0e1..00000000 --- a/backup/poker/turn.h +++ /dev/null @@ -1,106 +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 "poker.h" -#include "winner.h" -#include "../util/rand.h" - -#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_TURN_MAX_RAISES 0x02 - -/** The turn that a player/the AI decided to do for its turn */ -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; - -/** - * Returns the AI result for a turn done by a non human player. - * - * @param poker Poker game instance to use. - * @param playerIndex Player index to get the turn for. - * @return Some information about the move the player is trying to perform. - */ -pokerturn_t pokerTurnGet(poker_t *poker, uint8_t playerIndex); - -/** - * Perform the turn's action. - * - * @param poker Poker game instance. - * @param player Player instance. - * @param turn Turn to action. - */ -void pokerTurnAction(poker_t *poker, pokerplayer_t *player, pokerturn_t *turn); - -/** - * Return a turn action for the player being out. - * - * @param poker Poker game instance. - * @param player Player index. - * @return A turn for an out action. - */ -pokerturn_t pokerTurnOut(poker_t *poker, uint8_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 check as a player. - * - * @param poker Poker game instance. - * @param player Player index for who is checking. - * @return A turn for a check action. - */ -pokerturn_t pokerTurnCheck(poker_t *poker, uint8_t player); - -/** - * Perform a call as a player - * - * @param poker Poker game instance. - * @param player Player index who is calling. - * @return A turn for a call action. - */ -pokerturn_t pokerTurnCall(poker_t *poker, uint8_t player); - -/** - * Perform a bet 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 pokerTurnRaise(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 playerIndex Poker player index. - * @return True if the player can check, false if they need to call first. - */ -bool pokerTurnCanPlayerCheck(poker_t *poker, uint8_t playerIndex); \ No newline at end of file diff --git a/backup/poker/winner.c b/backup/poker/winner.c deleted file mode 100644 index 2d2edbc0..00000000 --- a/backup/poker/winner.c +++ /dev/null @@ -1,434 +0,0 @@ -/** - * Copyright (c) 2021 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "winner.h" - -void pokerWinnerHandGetFull( - pokerdealer_t *dealer, pokerplayer_t *player, card_t *cards -) { - uint8_t i; - - // Add the dealer hand - for(i = 0; i < dealer->cardsFacing; i++) { - cards[i] = dealer->cards[i]; - } - - // Add the player hand - for(i = 0; i < player->cardCount; i++) { - cards[i+dealer->cardsFacing] = player->cards[i]; - } - - // Sort by card value - cardHandSort(cards, dealer->cardsFacing + player->cardCount); -} - -void pokerWinnerPlayerGet( - pokerdealer_t *dealer, 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 = dealer->cardsFacing + player->cardCount; - pokerWinnerHandGetFull(dealer, player, winning->full); - - // Reset the winning status. - winning->setSize = 0; - - //////////////////////// Now look for the winning set //////////////////////// - - // Royal / Straight Flush - for(i = 0; i < winning->fullSize; i++) { - card = winning->full[i]; - number = cardGetNumber(card); - if(number < CARD_FIVE) continue; - - suit = cardGetSuit(card); - winning->setSize = 1; - - // Now look for the matching cards (Reverse order to order from A to 10) - for(j = 1; j <= 4; j++) { - l = number == CARD_FIVE && j == 4 ? CARD_ACE : number - j;//Ace low. - index = cardContains(winning->full, winning->fullSize, cardGet(l, suit)); - if(index == -1) break; - winning->set[j] = winning->full[index]; - winning->setSize++; - } - - // Check if has all necessary cards. - if(winning->setSize < POKER_WINNING_SET_SIZE) continue; - - // Add self to array - winning->set[0] = winning->full[i]; - winning->type = ( - number == CARD_ACE ? POKER_WINNING_TYPE_ROYAL_FLUSH : - POKER_WINNING_TYPE_STRAIGHT_FLUSH - ); - return; - } - - // Four of a kind. - winning->setSize = 0; - for(i = 0; i < winning->fullSize; i++) { - card = winning->full[i]; - number = cardGetNumber(card); - pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs); - if(pairCount < CARD_SUIT_COUNT) continue; - - winning->setSize = pairCount; - for(j = 0; j < pairCount; j++) winning->set[j] = winning->full[pairs[j]]; - winning->type = POKER_WINNING_TYPE_FOUR_OF_A_KIND; - _pokerWinnerFillRemaining(winning); - return; - } - - // Full House - winning->setSize = 0; - for(i = 0; i < winning->fullSize; i++) { - // Check we haven't already added this card. - card = winning->full[i]; - if(cardContains(winning->set, winning->setSize, card) != -1) continue; - - number = cardGetNumber(card); - pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs); - - // Did we find either two pair or three pair? - if(pairCount != 2 && pairCount != 3) continue; - if(winning->setSize == 3) pairCount = 2;//Clamp to 5 max. - - // Copy found pairs. - for(j = 0; j < pairCount; j++) { - winning->set[winning->setSize + j] = winning->full[pairs[j]]; - } - winning->setSize += pairCount; - - // Winned? - if(winning->setSize != POKER_WINNING_SET_SIZE) continue; - winning->type = POKER_WINNING_TYPE_FULL_HOUSE; - printf("Full House\n"); - return; - } - - // Flush (5 same suit) - for(i = 0; i < winning->fullSize; i++) { - card = winning->full[i]; - suit = cardGetSuit(card); - winning->setSize = 1; - for(j = i+1; j < winning->fullSize; j++) { - if(cardGetSuit(winning->full[j]) != suit) continue; - winning->set[winning->setSize] = winning->full[j]; - winning->setSize++; - if(winning->setSize == POKER_WINNING_SET_SIZE) break; - } - if(winning->setSize < POKER_WINNING_SET_SIZE) continue; - winning->set[0] = winning->full[0]; - winning->type = POKER_WINNING_TYPE_FLUSH; - return; - } - - // Straight (sequence any suit) - winning->setSize = 0; - for(i = 0; i < winning->fullSize; i++) { - card = winning->full[i]; - number = cardGetNumber(card); - if(number < CARD_FIVE) continue; - winning->setSize = 1; - - for(j = 1; j <= 4; j++) { - l = number == CARD_FIVE && j == 4 ? CARD_ACE : number - j;//Ace low. - index = cardContainsNumber(winning->full, winning->fullSize, l); - if(index == -1) break; - winning->set[j] = winning->full[index]; - winning->setSize++; - } - - // Check if has all necessary cards. - if(winning->setSize < POKER_WINNING_SET_SIZE) continue; - winning->set[0] = winning->full[i]; - winning->type = POKER_WINNING_TYPE_STRAIGHT; - return; - } - - // Three of a kind - winning->setSize = 0; - for(i = 0; i < winning->fullSize; i++) { - card = winning->full[i]; - number = cardGetNumber(card); - pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs); - if(pairCount != 3) continue; - - winning->setSize = pairCount; - for(j = 0; j < pairCount; j++) winning->set[j] = winning->full[pairs[j]]; - winning->type = POKER_WINNING_TYPE_THREE_OF_A_KIND; - _pokerWinnerFillRemaining(winning); - return; - } - - // Two Pair - winning->setSize = 0; - for(i = 0; i < winning->fullSize; i++) { - card = winning->full[i];// Check we haven't already added this card. - if(cardContains(winning->set, winning->setSize, card) != -1) { - continue; - } - - number = cardGetNumber(card); - pairCount = cardCountPairs(winning->full, winning->fullSize, number, pairs); - if(pairCount != 2) continue; - - for(j = 0; j < pairCount; j++) { - winning->set[j] = winning->full[winning->setSize + pairs[j]]; - } - // arrayCopy(sizeof(int32_t), pairs, pairCount, winning->set+winning->setSize); - winning->setSize += pairCount; - if(winning->setSize != 4) continue; - - winning->type = POKER_WINNING_TYPE_TWO_PAIR; - _pokerWinnerFillRemaining(winning); - return; - } - - // Pair - if(winning->setSize == 2) { - winning->type = POKER_WINNING_TYPE_PAIR; - _pokerWinnerFillRemaining(winning); - return; - } - - // High card - winning->setSize = 0; - _pokerWinnerFillRemaining(winning); - winning->type = POKER_WINNNIG_TYPE_HIGH_CARD; - - return; -} - -void _pokerWinnerFillRemaining(pokerplayerwinning_t *winning) { - uint8_t i, highest, current; - card_t highestCard, currentCard; - - // Set the kicker - winning->kicker = 0xFF; - - // Fill the remaining cards - while(winning->setSize < POKER_WINNING_SET_SIZE) { - highest = 0xFF; - - for(i = 0; i < winning->fullSize; i++) { - currentCard = winning->full[i]; - if(cardContains(winning->set, winning->setSize, currentCard) != -1) { - continue; - } - - if(highest == 0xFF) { - highestCard = currentCard; - highest = cardGetNumber(highestCard); - } else { - current = cardGetNumber(currentCard); - if(current != CARD_ACE && current < highest) continue; - highestCard = currentCard; - highest = current; - } - } - - if(highest == 0xFF) break; - winning->set[winning->setSize++] = highestCard; - } - cardHandSort(winning->set, winning->setSize); -} - -card_t pokerWinnerCompare(pokerplayerwinning_t *left, pokerplayerwinning_t *right) { - uint8_t i, number; - card_t card; - int32_t index; - 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 pokerWinnerCalculate( - pokerwinner_t *winner, pokerdealer_t *dealer, pokerplayer_t *players -) { - uint8_t i, j, number, highNumber; - pokerplayerwinning_t *left, *right; - pokerplayer_t *player; - card_t card, highCard; - bool isWinner; - - winner->winnerCount = 0; - highCard = 0xFF; - - // Get winning sets - for(i = 0; i < POKER_PLAYER_COUNT; i++) { - left = winner->winnings + i; - left->type = POKER_WINNING_TYPE_NULL; - player = players + i; - if(!pokerPlayerIsInRound(player)) continue; - - // Get the players' winning state. - pokerWinnerPlayerGet(dealer, player, left); - } - - // Compare against each player - for(i = 0; i < POKER_PLAYER_COUNT; i++) { - left = winner->winnings + i; - if(left->type == POKER_WINNING_TYPE_NULL) continue; - - isWinner = true; - highNumber = 0xFF; - - for(j = 0; j < POKER_PLAYER_COUNT; j++) { - if(i == j) continue; - right = winner->winnings + j; - if(right->type == POKER_WINNING_TYPE_NULL) continue; - - // Am I the better hand / Is it the better hand? - if(left->type < right->type) continue; - if(left->type > right->type) { - isWinner = false; - break; - } - - // Equal, compare hands. - card = pokerWinnerCompare(left, right); - if(card == 0xFF) { - isWinner = false; - break; - } - - // Determine high card. - number = cardGetNumber(card); - if(highNumber == 0xFF || number == CARD_ACE || number > highNumber) { - highCard = card; - highNumber = number; - } - } - - if(!isWinner) continue; - left->kicker = highCard; - winner->winners[winner->winnerCount++] = i; - } -} - -card_t pokerWinnerGetBestCard(card_t *cards, uint8_t cardCount) { - uint8_t i, number, bestNumber; - card_t card, bestCard; - - bestNumber = 0xFF; - - for(i = 0; i < cardCount; i++) { - card = cards[i]; - number = cardGetNumber(card); - if(number == CARD_ACE) return card; - if(bestNumber != 0xFF && number <= bestNumber) continue; - - bestCard = card; - bestNumber = number; - } - - return bestNumber; -} - -float pokerWinnerGetTypeConfidence(uint8_t type) { - switch(type) { - case POKER_WINNING_TYPE_ROYAL_FLUSH: - return POKER_WINNNIG_CONFIDENCE_ROYAL_FLUSH; - case POKER_WINNING_TYPE_STRAIGHT_FLUSH: - return POKER_WINNNIG_CONFIDENCE_STRAIGHT_FLUSH; - case POKER_WINNING_TYPE_FOUR_OF_A_KIND: - return POKER_WINNNIG_CONFIDENCE_FOUR_OF_A_KIND; - case POKER_WINNING_TYPE_FULL_HOUSE: - return POKER_WINNNIG_CONFIDENCE_FULL_HOUSE; - case POKER_WINNING_TYPE_FLUSH: - return POKER_WINNNIG_CONFIDENCE_FLUSH; - case POKER_WINNING_TYPE_STRAIGHT: - return POKER_WINNNIG_CONFIDENCE_STRAIGHT; - case POKER_WINNING_TYPE_THREE_OF_A_KIND: - return POKER_WINNNIG_CONFIDENCE_THREE_OF_A_KIND; - case POKER_WINNING_TYPE_TWO_PAIR: - return POKER_WINNNIG_CONFIDENCE_TWO_PAIR; - case POKER_WINNING_TYPE_PAIR: - return POKER_WINNNIG_CONFIDENCE_PAIR; - default: - return POKER_WINNNIG_CONFIDENCE_HIGH_CARD; - } -} - -float pokerWinnerGetCardWeight(card_t card) { - uint8_t number; - number = cardGetNumber(card); - return ((float)number + 1)/((float)CARD_ACE + 1); -} \ No newline at end of file diff --git a/backup/poker/winner.h b/backup/poker/winner.h deleted file mode 100644 index 768cf1eb..00000000 --- a/backup/poker/winner.h +++ /dev/null @@ -1,148 +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 "card.h" -#include "player.h" -#include "winner.h" -#include "dealer.h" - -/** Size of the FULL hand used to calculate a winning. */ -#define POKER_WINNING_FULL_SIZE POKER_PLAYER_HAND+POKER_DEALER_HAND_SIZE - -/** How many cards make a winning set */ -#define POKER_WINNING_SET_SIZE 5 - -/** Winning Types */ -#define POKER_WINNING_TYPE_NULL 0x00 -#define POKER_WINNING_TYPE_ROYAL_FLUSH 0x01 -#define POKER_WINNING_TYPE_STRAIGHT_FLUSH 0x02 -#define POKER_WINNING_TYPE_FOUR_OF_A_KIND 0x03 -#define POKER_WINNING_TYPE_FULL_HOUSE 0x04 -#define POKER_WINNING_TYPE_FLUSH 0x05 -#define POKER_WINNING_TYPE_STRAIGHT 0x06 -#define POKER_WINNING_TYPE_THREE_OF_A_KIND 0x07 -#define POKER_WINNING_TYPE_TWO_PAIR 0x08 -#define POKER_WINNING_TYPE_PAIR 0x09 -#define POKER_WINNNIG_TYPE_HIGH_CARD 0x0A - -#define POKER_WINNNIG_CONFIDENCE_ROYAL_FLUSH 1.0f -#define POKER_WINNNIG_CONFIDENCE_STRAIGHT_FLUSH 0.99f -#define POKER_WINNNIG_CONFIDENCE_FOUR_OF_A_KIND 0.9f -#define POKER_WINNNIG_CONFIDENCE_FULL_HOUSE 0.85f -#define POKER_WINNNIG_CONFIDENCE_FLUSH 0.8f -#define POKER_WINNNIG_CONFIDENCE_STRAIGHT 0.7f -#define POKER_WINNNIG_CONFIDENCE_THREE_OF_A_KIND 0.5f -#define POKER_WINNNIG_CONFIDENCE_TWO_PAIR 0.4f -#define POKER_WINNNIG_CONFIDENCE_PAIR 0.2f -#define POKER_WINNNIG_CONFIDENCE_HIGH_CARD 0.1f - -/** Holds information about a player's winning state */ -typedef struct { - /** The full set of both the dealer and player's hand */ - card_t full[POKER_WINNING_FULL_SIZE]; - uint8_t fullSize; - - /** Holds the winning set */ - card_t set[POKER_WINNING_SET_SIZE]; - uint8_t setSize; - - /** Winning Type */ - uint8_t type; - - /** If there was a kicker card it will be here, otherwise -1 for no kicker */ - card_t kicker; -} pokerplayerwinning_t; - -typedef struct { - /** Winning States */ - pokerplayerwinning_t winnings[POKER_PLAYER_COUNT]; - uint8_t winners[POKER_PLAYER_COUNT]; - uint8_t winnerCount; -} pokerwinner_t; - -/** - * Returns the full hand for a given player including the best cards on the - * bench. - * - * @param dealer Poker game dealer instance. - * @param player Poker player game instance. - * @param cards Array of at least 7 length to store the array. - */ -void pokerWinnerHandGetFull( - pokerdealer_t *dealer, pokerplayer_t *player, card_t *cards -); - -/** - * Calculates and returns the winning state for a given player - * - * @param dealer Poker game dealer instance. - * @param players Array of poker players. - * @param winning Pointer to the poker winning to fill out. - * @return The winning state for this player. - */ -void pokerWinnerPlayerGet( - pokerdealer_t *dealer, pokerplayer_t *player, pokerplayerwinning_t *winning -); - -/** - * Fills the remaining cards for a given poker player winning hand. Essentially - * this will just take the highest cards and slot them into the array. - * @param winning Pointer to the poker winning to fill out. - */ -void _pokerWinnerFillRemaining(pokerplayerwinning_t *winning); - -/** - * Compares two winning sets. The returned card is the kicker if the LEFT side - * is the winner. If LEFT is not a winner then 0xFF will be returned. - * - * @param left Left winning set. - * @param right Right winning set. - * @return The kicker card from left's hand or 0xFF if left is not the winner. - */ -card_t pokerWinnerCompare( - pokerplayerwinning_t *left, pokerplayerwinning_t *right -); - -/** - * Determines the winning player for the game. Values will be stored back into - * the poker winning state. - * - * @param winner Location to store the winner state. - * @param dealer Poker game dealer instance. - * @param players Array of poker players. - */ -void pokerWinnerCalculate( - pokerwinner_t *winner, pokerdealer_t *dealer, pokerplayer_t *players -); - -/** - * Get the best valued card from a given hand. - * - * @param cards Array of cards. - * @param cardCount Count of cards in the array - * @return The best card within the array. - */ -card_t pokerWinnerGetBestCard(card_t *cards, uint8_t cardCount); - - -/** - * Get the confidence of the bet for a given winning type. - * - * @param type Winning type type. - * @return The confidence. - */ -float pokerWinnerGetTypeConfidence(uint8_t type); - -/** - * Get the weight of a card. - * - * @param card Card to get the weight of. - * @return The cards' weight. - */ -float pokerWinnerGetCardWeight(card_t card); \ No newline at end of file