Refactor round 1
This commit is contained in:
@ -38,12 +38,14 @@
|
||||
#include "input/input.h"
|
||||
|
||||
// Poker Game Logic
|
||||
#include "poker/bet.h"
|
||||
#include "poker/card.h"
|
||||
#include "poker/chip.h"
|
||||
#include "poker/dealer.h"
|
||||
#include "poker/player.h"
|
||||
#include "poker/poker.h"
|
||||
#include "poker/render.h"
|
||||
#include "poker/strings.h"
|
||||
#include "poker/winner.h"
|
||||
|
||||
// Utility Objects
|
||||
#include "util/array.h"
|
||||
|
26
include/dawn/poker/bet.h
Normal file
26
include/dawn/poker/bet.h
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
|
||||
/** How many chips each player has by defautl */
|
||||
#define POKER_BET_PLAYER_CHIPS_DEFAULT 10000
|
||||
|
||||
/** 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 */
|
||||
uint32_t blindSmall, blindBig;
|
||||
|
||||
/** Current pot of chips */
|
||||
uint32_t pot;
|
||||
} pokerbet_t;
|
@ -1,8 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
27
include/dawn/poker/dealer.h
Normal file
27
include/dawn/poker/dealer.h
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* 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 "../display/texture.h"
|
||||
#include "../display/tileset.h"
|
||||
#include "../display/primitive.h"
|
||||
|
||||
/** How many cards the dealer can hold in their hand */
|
||||
#define POKER_DEALER_HAND 5
|
||||
|
||||
/** Representation of the dealer state */
|
||||
typedef struct {
|
||||
/** Dealer Hand */
|
||||
card_t cards[POKER_DEALER_HAND];
|
||||
uint8_t cardsFacing;
|
||||
|
||||
texture_t dealerTexture;
|
||||
tileset_t dealerTileset;
|
||||
primitive_t dealerPrimitive;
|
||||
} pokerdealer_t;
|
@ -7,14 +7,24 @@
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "bet.h"
|
||||
#include "dealer.h"
|
||||
#include "card.h"
|
||||
#include "../display/texture.h"
|
||||
#include "../display/primitive.h"
|
||||
#include "../display/tileset.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 0x01
|
||||
|
||||
@ -27,6 +37,11 @@
|
||||
/** 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 */
|
||||
@ -42,10 +57,11 @@ typedef struct {
|
||||
/** Current bet in current round player has placed */
|
||||
uint32_t currentBet;
|
||||
|
||||
|
||||
// Rendering assets
|
||||
texture_t bodyTexture;
|
||||
primitive_t bodyPrimitive;
|
||||
|
||||
texture_t faceTexture;
|
||||
primitive_t facePrimitive;
|
||||
primitive_t facePrimitive;
|
||||
} pokerplayer_t;
|
@ -7,15 +7,19 @@
|
||||
|
||||
#pragma once
|
||||
#include "../libs.h"
|
||||
#include "bet.h"
|
||||
#include "dealer.h"
|
||||
#include "player.h"
|
||||
#include "card.h"
|
||||
#include "render.h"
|
||||
#include "winner.h"
|
||||
|
||||
#include "../display/camera.h"
|
||||
#include "../display/shader.h"
|
||||
#include "../display/texture.h"
|
||||
#include "../display/tileset.h"
|
||||
#include "../display/framebuffer.h"
|
||||
#include "../display/primitive.h"
|
||||
|
||||
/** Rounds that the game can be in */
|
||||
#define POKER_ROUND_MATCH 0x00
|
||||
@ -31,22 +35,9 @@
|
||||
#define POKER_ROUND_BET3 0x0A
|
||||
#define POKER_ROUND_WINNER 0x0B
|
||||
|
||||
/** How many cards the dealer can hold in their hand */
|
||||
#define POKER_DEALER_HAND 5
|
||||
|
||||
/** How many cards the grave can hold */
|
||||
#define POKER_GRAVE_SIZE CARD_DECK_SIZE
|
||||
|
||||
/** How many players in a poker game (excludes dealer) */
|
||||
#define POKER_PLAYER_COUNT 5
|
||||
|
||||
/** How many chips each player has by defautl */
|
||||
#define POKER_PLAYER_CHIPS_DEFAULT 10000
|
||||
|
||||
/** The default blind cost for the big blind. Small Blind is half this */
|
||||
#define POKER_BLIND_BIG_DEFAULT 600
|
||||
#define POKER_BLIND_SMALL_DEFAULT (POKER_BLIND_BIG_DEFAULT/2)
|
||||
|
||||
/** GUI Height fix (To keep gui scaling nicely we use a fixed height) */
|
||||
#define POKER_GUI_HEIGHT 2160
|
||||
|
||||
@ -57,44 +48,10 @@
|
||||
#define POKER_TURN_CARD_COUNT 1
|
||||
#define POKER_RIVER_CARD_COUNT 1
|
||||
|
||||
/** 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
|
||||
|
||||
/** How many cards make a winning set */
|
||||
#define POKER_WINNING_SET_SIZE 5
|
||||
|
||||
/** Holds information about the winning player state */
|
||||
typedef struct {
|
||||
/** The full set of both the dealer and player's hand */
|
||||
card_t full[POKER_PLAYER_HAND + POKER_DEALER_HAND];
|
||||
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;
|
||||
} pokerwinning_t;
|
||||
|
||||
typedef struct {
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Poker Logic Variables
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Current Card Deck */
|
||||
card_t deck[CARD_DECK_SIZE];
|
||||
uint8_t deckSize;
|
||||
@ -103,50 +60,44 @@ typedef struct {
|
||||
card_t grave[POKER_GRAVE_SIZE];
|
||||
uint8_t graveSize;
|
||||
|
||||
/** Blinds */
|
||||
uint32_t blindSmall, blindBig;
|
||||
|
||||
/** Dealer Hand */
|
||||
card_t cards[POKER_DEALER_HAND];
|
||||
uint8_t cardsFacing;
|
||||
|
||||
/** Poker betting state */
|
||||
pokerbet_t bet;
|
||||
|
||||
/** Player States */
|
||||
pokerdealer_t dealer;
|
||||
pokerplayer_t players[POKER_PLAYER_COUNT];
|
||||
|
||||
/** Winning States */
|
||||
pokerwinning_t winnings[POKER_PLAYER_COUNT];
|
||||
uint8_t winners[POKER_PLAYER_COUNT];
|
||||
uint8_t winnerCount;
|
||||
|
||||
/** The current round the game is on */
|
||||
uint8_t round;
|
||||
pokerwinner_t winner;
|
||||
|
||||
/** The current player that is the dealer */
|
||||
uint8_t roundDealer;
|
||||
uint8_t roundSmallBlind;
|
||||
uint8_t roundBigBlind;
|
||||
|
||||
/** Current pot of chips */
|
||||
uint32_t pot;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Round variables
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
uint32_t roundTextCounter;
|
||||
|
||||
/** The current round the game is on */
|
||||
uint8_t round;
|
||||
|
||||
/** For Betting round, which player is currently betting */
|
||||
uint8_t roundBetCurrent;
|
||||
|
||||
uint32_t roundTextCounter;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Rendering Variables
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Frames to hold the world and GUI render outputs */
|
||||
framebuffer_t frameWorld, frameGui;
|
||||
|
||||
/** Game's Font */
|
||||
font_t font;
|
||||
|
||||
/** Game's Shader */
|
||||
shader_t shader;
|
||||
|
||||
/** Camera for the world and the GUI */
|
||||
camera_t cameraWorld, cameraGui, cameraTest;
|
||||
|
||||
@ -162,19 +113,6 @@ typedef struct {
|
||||
/** Information about the current rendered text */
|
||||
fonttextinfo_t *talkTextInfo;
|
||||
|
||||
/** Match Scene Variables */
|
||||
float matchStart;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
texture_t dealerTexture;
|
||||
tileset_t dealerTileset;
|
||||
primitive_t dealerPrimitive;
|
||||
|
||||
texture_t chipTexture;
|
||||
primitive_t chipPrimitive;
|
||||
|
54
include/dawn/poker/winner.h
Normal file
54
include/dawn/poker/winner.h
Normal file
@ -0,0 +1,54 @@
|
||||
/**
|
||||
* 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 "dealer.h"
|
||||
|
||||
/** Size of the FULL hand used to calculate a winning. */
|
||||
#define POKER_WINNING_FULL_SIZE POKER_PLAYER_HAND+POKER_DEALER_HAND
|
||||
|
||||
/** 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
|
||||
|
||||
/** 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;
|
23
src/poker/bet.c
Normal file
23
src/poker/bet.c
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "bet.h"
|
||||
|
||||
void pokerBetPlayer(poker_t *poker, pokerplayer_t *player, int32_t chips) {
|
||||
poker->bet.pot += chips;
|
||||
player->chips -= chips;
|
||||
player->currentBet += chips;
|
||||
}
|
||||
|
||||
void pokerBetTakeBlinds(poker_t *poker) {
|
||||
pokerBetPlayer(poker, poker->players + poker->roundSmallBlind,
|
||||
poker->bet.blindSmall
|
||||
);
|
||||
pokerBetPlayer(poker, poker->players + poker->roundBigBlind,
|
||||
poker->bet.blindBig
|
||||
);
|
||||
}
|
23
src/poker/bet.h
Normal file
23
src/poker/bet.h
Normal file
@ -0,0 +1,23 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
|
||||
/**
|
||||
* Let a player bet chips into the pot.
|
||||
*
|
||||
* @param poker Poker game instance.
|
||||
* @param player Poker player instance.
|
||||
* @param chips Chips to bet.
|
||||
*/
|
||||
void pokerBetPlayer(poker_t *poker, pokerplayer_t *player, int32_t chips);
|
||||
|
||||
/**
|
||||
* Takes the current blinds from the correct players.
|
||||
*
|
||||
* @param poker Poker game to take the blinds from.
|
||||
*/
|
||||
void pokerBetTakeBlinds(poker_t *poker);
|
@ -45,6 +45,8 @@ void cardDeal(card_t *source, uint8_t *sourceSize, card_t *dest,
|
||||
|
||||
/**
|
||||
* Sort a hand of cards. Cards are ordered in descending weight, aces are high.
|
||||
* Cards will be grouped by their suits, e.g. CARD_CLUBS_TWO will appear before
|
||||
* CARD_DIAMONDS_KING.
|
||||
*
|
||||
* @param cards Hand of cards to sort.
|
||||
* @param length Length of the array of cards.
|
||||
|
17
src/poker/dealer.c
Normal file
17
src/poker/dealer.c
Normal file
@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
#include "dealer.h"
|
||||
|
||||
void pokerDealerDeal(poker_t *poker, uint8_t count) {
|
||||
uint8_t i;
|
||||
for(i = 0; i < count; i++) {
|
||||
cardDeal(
|
||||
poker->deck, &poker->deckSize,
|
||||
poker->dealer.cards, &poker->dealer.cardsFacing
|
||||
);
|
||||
}
|
||||
}
|
17
src/poker/dealer.h
Normal file
17
src/poker/dealer.h
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "card.h"
|
||||
|
||||
/**
|
||||
* Deals cards to each player from the dealers' deck. Cards are dealt one to
|
||||
* each player $count times.
|
||||
*
|
||||
* @param poker Poker game instance
|
||||
* @param count Count of cards to deal.
|
||||
*/
|
||||
void pokerDealerDeal(poker_t *poker, uint8_t count);
|
@ -7,12 +7,6 @@
|
||||
|
||||
#include "player.h"
|
||||
|
||||
void pokerPlayerBet(poker_t *poker, pokerplayer_t *player, int32_t chips) {
|
||||
poker->pot += chips;
|
||||
player->chips -= chips;
|
||||
player->currentBet += chips;
|
||||
}
|
||||
|
||||
bool pokerPlayerIsAlive(pokerplayer_t *player) {
|
||||
return !(player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT));
|
||||
}
|
||||
@ -36,340 +30,4 @@ void pokerPlayerDealAll(poker_t *poker, uint8_t count) {
|
||||
pokerPlayerDeal(poker, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pokerPlayerGetFullHand(poker_t *poker,pokerplayer_t *player,card_t *cards){
|
||||
uint8_t i;
|
||||
|
||||
// Add the dealer hand
|
||||
for(i = 0; i < poker->cardsFacing; i++) {
|
||||
cards[i] = poker->cards[i];
|
||||
}
|
||||
|
||||
// Add the player hand
|
||||
for(i = 0; i < player->cardCount; i++) {
|
||||
cards[i+poker->cardsFacing] = player->cards[i];
|
||||
}
|
||||
|
||||
// Sort by card value
|
||||
cardHandSort(cards, poker->cardsFacing+player->cardCount);
|
||||
}
|
||||
|
||||
void pokerPlayerGetWinning(
|
||||
poker_t *poker, pokerplayer_t *player, pokerwinning_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)
|
||||
winning->fullSize = poker->cardsFacing + player->cardCount;
|
||||
pokerPlayerGetFullHand(poker, 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;
|
||||
pokerPlayerWinningFillRemaining(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;
|
||||
pokerPlayerWinningFillRemaining(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;
|
||||
pokerPlayerWinningFillRemaining(winning);
|
||||
return;
|
||||
}
|
||||
|
||||
// Pair
|
||||
if(winning->setSize == 2) {
|
||||
winning->type = POKER_WINNING_TYPE_PAIR;
|
||||
pokerPlayerWinningFillRemaining(winning);
|
||||
return;
|
||||
}
|
||||
|
||||
// High card
|
||||
winning->setSize = 0;
|
||||
pokerPlayerWinningFillRemaining(winning);
|
||||
winning->type = POKER_WINNNIG_TYPE_HIGH_CARD;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void pokerPlayerWinningFillRemaining(pokerwinning_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;
|
||||
}
|
||||
}
|
||||
|
||||
winning->set[winning->setSize++] = highestCard;
|
||||
}
|
||||
cardHandSort(winning->set, winning->setSize);
|
||||
}
|
||||
|
||||
card_t pokerPlayerCompareWinning(pokerwinning_t *left, pokerwinning_t *right) {
|
||||
uint8_t i, number;
|
||||
card_t card;
|
||||
int32_t index;
|
||||
|
||||
card_t highCardLeft, highCardRight;
|
||||
uint8_t highNumberLeft, highNumberRight;
|
||||
|
||||
highNumberLeft = 0xFF;
|
||||
highNumberRight = 0xFF;
|
||||
|
||||
for(i = 0; i < left->setSize; i++) {
|
||||
card = left->set[i];
|
||||
number = cardGetNumber(card);
|
||||
if(highNumberLeft != 0xFF && number < highNumberLeft) continue;// Quick check
|
||||
index = cardContainsNumber(right->set, right->setSize, number);
|
||||
if(index != -1) continue;// In other?
|
||||
|
||||
if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberRight < 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) continue;
|
||||
|
||||
if(highNumberRight == 0xFF||number == CARD_ACE||highNumberRight < number) {
|
||||
highNumberRight = number;
|
||||
highCardRight = card;
|
||||
}
|
||||
}
|
||||
|
||||
if(highNumberLeft < highNumberRight) return 0xFF;
|
||||
return highCardLeft;//Greater or Equal to.
|
||||
}
|
||||
|
||||
void pokerPlayerWinnerDetermine(poker_t *poker) {
|
||||
uint8_t i, j, number, highNumber;
|
||||
pokerwinning_t *left, *right;
|
||||
pokerplayer_t *player;
|
||||
card_t card, highCard;
|
||||
bool winner;
|
||||
|
||||
poker->winnerCount = 0;
|
||||
|
||||
// Get winning sets
|
||||
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
|
||||
left = poker->winnings + i;
|
||||
left->type = POKER_WINNING_TYPE_NULL;
|
||||
player = poker->players + i;
|
||||
if(!pokerPlayerIsAlive(player)) continue;
|
||||
|
||||
// Get the players' full hand.
|
||||
pokerPlayerGetWinning(poker, player, left);
|
||||
}
|
||||
|
||||
// Compare against each player
|
||||
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
|
||||
left = poker->winnings + i;
|
||||
if(left->type == POKER_WINNING_TYPE_NULL) continue;
|
||||
|
||||
winner = true;
|
||||
highNumber = 0xFF;
|
||||
|
||||
for(j = 0; j < POKER_PLAYER_COUNT; j++) {
|
||||
if(i == j) continue;
|
||||
right = poker->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) {
|
||||
winner = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Equal, compare hands.
|
||||
card = pokerPlayerCompareWinning(left, right);
|
||||
if(card == 0xFF) {
|
||||
winner = false;
|
||||
break;
|
||||
}
|
||||
|
||||
// Determine high card.
|
||||
number = cardGetNumber(card);
|
||||
if(highNumber == 0xFF || number == CARD_ACE || number > highNumber) {
|
||||
highCard = card;
|
||||
highNumber = number;
|
||||
}
|
||||
}
|
||||
|
||||
if(!winner) continue;
|
||||
left->kicker = highCard;
|
||||
poker->winners[poker->winnerCount++] = i;
|
||||
}
|
||||
}
|
||||
}
|
@ -8,15 +8,6 @@
|
||||
#include <dawn/dawn.h>
|
||||
#include "card.h"
|
||||
|
||||
/**
|
||||
* Let a player bet chips into the pot.
|
||||
*
|
||||
* @param poker Poker game instance.
|
||||
* @param player Poker player instance.
|
||||
* @param chips Chips to bet.
|
||||
*/
|
||||
void pokerPlayerBet(poker_t *poker, pokerplayer_t *player, int32_t chips);
|
||||
|
||||
/**
|
||||
* Returns true if the player is still alive and in the current game/
|
||||
* Defined as: Not out, not folded.
|
||||
@ -49,50 +40,4 @@ void pokerPlayerDeal(poker_t *poker, pokerplayer_t *player);
|
||||
* @param poker Poker game instance.
|
||||
* @param count Count of cards to deal.
|
||||
*/
|
||||
void pokerPlayerDealAll(poker_t *poker, uint8_t count);
|
||||
|
||||
/**
|
||||
* Returns the full hand for a given player including the best cards on the
|
||||
* bench.
|
||||
*
|
||||
* @param poker Poker game instance.
|
||||
* @param player Poker player game instance.
|
||||
* @param cards Array of at least 7 length to store the array.
|
||||
*/
|
||||
void pokerPlayerGetFullHand(poker_t *poker,pokerplayer_t *player,card_t *cards);
|
||||
|
||||
/**
|
||||
* Calculates and returns the winning state for a given player
|
||||
*
|
||||
* @param poker Poker game instance.
|
||||
* @param player Player game instance.
|
||||
* @param winning Pointer to the poker winning to fill out.
|
||||
* @return The winning state for this player.
|
||||
*/
|
||||
void pokerPlayerGetWinning(
|
||||
poker_t *poker, pokerplayer_t *player, pokerwinning_t *winning
|
||||
);
|
||||
|
||||
/**
|
||||
* Fills the remaining cards for a given poker player winning hand.
|
||||
* @param winning Pointer to the poker winning to fill out.
|
||||
*/
|
||||
void pokerPlayerWinningFillRemaining(pokerwinning_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 pokerPlayerCompareWinning(pokerwinning_t *left, pokerwinning_t *right);
|
||||
|
||||
/**
|
||||
* Determines the winning player for the game. Values will be stored back into
|
||||
* the poker winning state.
|
||||
*
|
||||
* @param poker Poker game instance.
|
||||
*/
|
||||
void pokerPlayerWinnerDetermine(poker_t *poker);
|
||||
void pokerPlayerDealAll(poker_t *poker, uint8_t count);
|
@ -12,8 +12,7 @@ void pokerBlindsInit(poker_t *poker) {
|
||||
poker->round = POKER_ROUND_BLINDS;
|
||||
|
||||
// Now take blinds
|
||||
pokerPlayerBet(poker,poker->players+poker->roundSmallBlind, poker->blindSmall);
|
||||
pokerPlayerBet(poker,poker->players+poker->roundBigBlind, poker->blindBig);
|
||||
pokerBetTakeBlinds(poker);
|
||||
|
||||
printf("Blinds Taken\n");
|
||||
pokerDealInit(poker);
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
#include <dawn/dawn.h>
|
||||
#include "deal.h"
|
||||
#include "../player.h"
|
||||
#include "../bet.h"
|
||||
|
||||
/**
|
||||
* Initializes the blinds round.
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include "flop.h"
|
||||
|
||||
void pokerFlopInit(poker_t *poker) {
|
||||
uint8_t count, i;
|
||||
uint8_t count;
|
||||
|
||||
if(poker->round == POKER_ROUND_BET0) {
|
||||
printf("Poker Flop Start\n");
|
||||
@ -28,12 +28,7 @@ void pokerFlopInit(poker_t *poker) {
|
||||
poker->deckSize--;
|
||||
|
||||
// Flops
|
||||
for(i = 0; i < count; i++) {
|
||||
cardDeal(
|
||||
poker->deck, &poker->deckSize,
|
||||
poker->cards, &poker->cardsFacing
|
||||
);
|
||||
}
|
||||
pokerDealerDeal(poker, count);
|
||||
|
||||
pokerBetInit(poker);
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "bet.h"
|
||||
#include "../dealer.h"
|
||||
#include "../card.h"
|
||||
|
||||
void pokerFlopInit(poker_t *poker);
|
@ -10,24 +10,24 @@ void pokerMatchInit(poker_t *poker, engine_t *engine) {
|
||||
uint8_t x;
|
||||
|
||||
// Look at the dealer
|
||||
poker->matchStart = engine->time.current;
|
||||
// poker->matchStart = engine->time.current;
|
||||
pokerLookAtPlayer(&poker->cameraWorld, POKER_SEAT_DEALER, 100);
|
||||
|
||||
// Reset the main game state. This does not init the round.
|
||||
poker->blindBig = POKER_BLIND_BIG_DEFAULT;
|
||||
poker->blindSmall = POKER_BLIND_SMALL_DEFAULT;
|
||||
poker->bet.blindBig = POKER_BET_BLIND_BIG_DEFAULT;
|
||||
poker->bet.blindSmall = POKER_BET_BLIND_SMALL_DEFAULT;
|
||||
poker->roundDealer = POKER_PLAYER_COUNT-2;
|
||||
poker->roundTextCounter = 0;
|
||||
poker->round = POKER_ROUND_MATCH;
|
||||
|
||||
for(x = 0; x < POKER_PLAYER_COUNT; x++) {
|
||||
poker->players[x].state = 0x00;
|
||||
poker->players[x].chips = POKER_PLAYER_CHIPS_DEFAULT;
|
||||
poker->players[x].chips = POKER_BET_PLAYER_CHIPS_DEFAULT;
|
||||
}
|
||||
printf("Match Start\n");
|
||||
// pokerStartInit(poker);
|
||||
}
|
||||
|
||||
void pokerMatchUpdate(poker_t *poker, engine_t *engine) {
|
||||
float matchDiff = poker->matchStart - engine->time.current;
|
||||
// float matchDiff = poker->matchStart - engine->time.current;
|
||||
}
|
@ -16,9 +16,9 @@ void pokerStartInit(poker_t *poker) {
|
||||
|
||||
// Prepare the initial game state
|
||||
poker->round = POKER_ROUND_DEAL;
|
||||
poker->pot = 0;
|
||||
poker->bet.pot = 0;
|
||||
poker->graveSize = 0;
|
||||
poker->cardsFacing = 0;
|
||||
poker->dealer.cardsFacing = 0;
|
||||
poker->deckSize = CARD_DECK_SIZE;
|
||||
for(i = 0; i < CARD_DECK_SIZE; i++) poker->deck[i] = i;
|
||||
|
||||
|
@ -7,6 +7,6 @@
|
||||
#include "winner.h"
|
||||
|
||||
void pokerWinnerInit(poker_t *poker) {
|
||||
pokerPlayerWinnerDetermine(poker);
|
||||
printf("Winner Count %u\n", poker->winnerCount);
|
||||
pokerWinnerCalculate(poker);
|
||||
printf("Winner Count %u\n", poker->winner.winnerCount);
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "../player.h"
|
||||
#include "../winner.h"
|
||||
|
||||
void pokerWinnerInit(poker_t *poker);
|
348
src/poker/winner.c
Normal file
348
src/poker/winner.c
Normal file
@ -0,0 +1,348 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "winner.h"
|
||||
|
||||
void pokerWinnerHandGetFull(poker_t *poker, pokerplayer_t *player,
|
||||
card_t *cards
|
||||
){
|
||||
uint8_t i;
|
||||
|
||||
// Add the dealer hand
|
||||
for(i = 0; i < poker->dealer.cardsFacing; i++) {
|
||||
cards[i] = poker->dealer.cards[i];
|
||||
}
|
||||
|
||||
// Add the player hand
|
||||
for(i = 0; i < player->cardCount; i++) {
|
||||
cards[i+poker->dealer.cardsFacing] = player->cards[i];
|
||||
}
|
||||
|
||||
// Sort by card value
|
||||
cardHandSort(cards, poker->dealer.cardsFacing + player->cardCount);
|
||||
}
|
||||
|
||||
void pokerWinnerPlayerGet(
|
||||
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->dealer.cardsFacing + player->cardCount;
|
||||
pokerWinnerHandGetFull(poker, 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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
card_t highCardLeft, highCardRight;
|
||||
uint8_t highNumberLeft, highNumberRight;
|
||||
|
||||
highNumberLeft = 0xFF;
|
||||
highNumberRight = 0xFF;
|
||||
|
||||
for(i = 0; i < left->setSize; i++) {
|
||||
card = left->set[i];
|
||||
number = cardGetNumber(card);
|
||||
if(highNumberLeft != 0xFF && number < highNumberLeft) continue;// Quick check
|
||||
index = cardContainsNumber(right->set, right->setSize, number);
|
||||
if(index != -1) continue;// In other?
|
||||
|
||||
if(highNumberLeft == 0xFF||number == CARD_ACE||highNumberRight < 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) continue;
|
||||
|
||||
if(highNumberRight == 0xFF||number == CARD_ACE||highNumberRight < number) {
|
||||
highNumberRight = number;
|
||||
highCardRight = card;
|
||||
}
|
||||
}
|
||||
|
||||
if(highNumberLeft < highNumberRight) return 0xFF;
|
||||
return highCardLeft;//Greater or Equal to.
|
||||
}
|
||||
|
||||
void pokerWinnerCalculate(poker_t *poker) {
|
||||
uint8_t i, j, number, highNumber;
|
||||
pokerwinner_t *winner;
|
||||
pokerplayerwinning_t *left, *right;
|
||||
pokerplayer_t *player;
|
||||
card_t card, highCard;
|
||||
bool isWinner;
|
||||
|
||||
winner = &poker->winner;
|
||||
winner->winnerCount = 0;
|
||||
|
||||
// Get winning sets
|
||||
for(i = 0; i < POKER_PLAYER_COUNT; i++) {
|
||||
left = winner->winnings + i;
|
||||
left->type = POKER_WINNING_TYPE_NULL;
|
||||
player = poker->players + i;
|
||||
if(!pokerPlayerIsAlive(player)) continue;
|
||||
|
||||
// Get the players' winning state.
|
||||
pokerWinnerPlayerGet(poker, 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;
|
||||
}
|
||||
}
|
62
src/poker/winner.h
Normal file
62
src/poker/winner.h
Normal file
@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <dawn/dawn.h>
|
||||
#include "card.h"
|
||||
#include "player.h"
|
||||
|
||||
/**
|
||||
* Returns the full hand for a given player including the best cards on the
|
||||
* bench.
|
||||
*
|
||||
* @param poker Poker game instance.
|
||||
* @param player Poker player game instance.
|
||||
* @param cards Array of at least 7 length to store the array.
|
||||
*/
|
||||
void pokerWinnerHandGetFull(poker_t *poker, pokerplayer_t *player,
|
||||
card_t *cards
|
||||
);
|
||||
|
||||
/**
|
||||
* Calculates and returns the winning state for a given player
|
||||
*
|
||||
* @param poker Poker game instance.
|
||||
* @param player Player game instance.
|
||||
* @param winning Pointer to the poker winning to fill out.
|
||||
* @return The winning state for this player.
|
||||
*/
|
||||
void pokerWinnerPlayerGet(
|
||||
poker_t *poker, 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 poker Poker game instance.
|
||||
*/
|
||||
void pokerWinnerCalculate(poker_t *poker);
|
Reference in New Issue
Block a user