More refactoring

This commit is contained in:
2024-09-10 00:07:15 -05:00
parent d5b3b6d619
commit 5fae94c722
14 changed files with 382 additions and 140 deletions

View File

@ -5,6 +5,7 @@
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Easing.cpp
String.cpp
Random.cpp
)

48
src/dawn/util/Easing.cpp Normal file
View File

@ -0,0 +1,48 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Easing.hpp"
using namespace Dawn;
float_t Easing::linear(float_t t) {
return t;
}
float_t Easing::easeInQuad(float_t t) {
return t * t;
}
float_t Easing::easeOutQuad(float_t t) {
return t * (2 - t);
}
float_t Easing::easeInOutQuad(float_t t) {
return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
}
float_t Easing::easeInCubic(float_t t) {
return t * t * t;
}
float_t Easing::easeOutCubic(float_t t) {
return (--t) * t * t + 1;
}
float_t Easing::easeInOutCubic(float_t t) {
return t < 0.5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1;
}
float_t Easing::easeInQuart(float_t t) {
return t * t * t * t;
}
float_t Easing::easeOutQuart(float_t t) {
return 1 - (--t) * t * t * t;
}
float_t Easing::easeInOutQuart(float_t t) {
return t < 0.5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t;
}

92
src/dawn/util/Easing.hpp Normal file
View File

@ -0,0 +1,92 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
namespace Dawn {
class Easing final {
public:
/**
* Linear easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t linear(float_t t);
/**
* Quadratic easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t easeInQuad(float_t t);
/**
* Quadratic easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t easeOutQuad(float_t t);
/**
* Quadratic easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t easeInOutQuad(float_t t);
/**
* Cubic easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t easeInCubic(float_t t);
/**
* Cubic easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t easeOutCubic(float_t t);
/**
* Cubic easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t easeInOutCubic(float_t t);
/**
* Quartic easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t easeInQuart(float_t t);
/**
* Quartic easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t easeOutQuart(float_t t);
/**
* Quartic easing function.
*
* @param t Time value between 0 and 1.
* @return Eased value.
*/
static float_t easeInOutQuart(float_t t);
};
}

View File

@ -23,6 +23,16 @@ namespace Dawn {
*/
static uint64_t next();
/**
* Returns a random number between 0 and RAND_MAX.
*
* @return Random number between 0 and RAND_MAX.
*/
template<typename T>
static T random() {
return (T)next();
}
/**
* Returns a random number between the provided min and max values.
*

View File

@ -42,7 +42,7 @@ int32_t Card::contains(
);
}
int32_t Card::containsNumber(
int32_t Card::containsValue(
const std::vector<struct Card> &deck,
const enum CardValue number
) {

View File

@ -29,6 +29,7 @@ namespace Dawn {
Queen = 10,
King = 11,
Ace = 12,
Invalid = 0xFF
};
/** Count of cards in each suit */
@ -77,7 +78,7 @@ namespace Dawn {
* @param number The number to look for.
* @returns The index that the first card is. -1 if not found.
*/
static int32_t containsNumber(
static int32_t containsValue(
const std::vector<struct Card> &deck,
const enum CardValue number
);
@ -132,7 +133,6 @@ namespace Dawn {
* @param cv Card value.
*/
Card(const uint8_t cv) : cardValue(cv) {
assertTrue(cv < CARD_DECK_SIZE, "Card value out of range");
}
/**

View File

@ -23,7 +23,7 @@ void PokerGame::newGame() {
void PokerGame::newRound() {
this->deck.clear();
Card::fillDeck(&this->deck);
Card::fillDeck(this->deck);
this->smallBlind = POKER_BLIND_SMALL_DEFAULT;
this->bigBlind = POKER_BLIND_BIG_DEFAULT;
@ -82,9 +82,9 @@ void PokerGame::takeBlinds() {
playerBigBlind->hasBetThisRound = false;
}
void PokerGame::setDealer(uint8_t dealer) {
void PokerGame::setDealer(const uint8_t dealer) {
uint8_t i, k;
PokerPlayer *player;
std::shared_ptr<PokerPlayer> player;
bool_t foundDealer;
bool_t foundSmall;
@ -123,44 +123,43 @@ uint8_t PokerGame::getRemainingPlayersCount() {
uint8_t count = 0;
auto it = this->players.begin();
while(it != this->players.end()) {
auto player = *it;
if(!player->isFolded && !player->isOut) count++;
if(!(*it)->isFolded && !(*it)->isOut) count++;
++it;
}
return count;
}
int32_t PokerGame::getCurrentCallValue() {
assertTrue(this->pots.size() > 0);
assertTrue(this->pots.size() > 0, "No pots?");
return this->pots.back().call;
}
void PokerGame::burnCard() {
assertTrue(this->deck.size() > 0);
assertTrue(this->deck.size() > 0, "No cards to burn.");
auto card = this->deck.back();
this->deck.pop_back();
this->grave.push_back(card);
}
void PokerGame::dealCard(PokerPlayer *player) {
assertTrue(this->deck.size() > 0);
void PokerGame::dealCard(PokerPlayer &player) {
assertTrue(this->deck.size() > 0, "No cards to deal.");
auto card = this->deck.back();
this->deck.pop_back();
player->hand.push_back(card);
player.hand.push_back(card);
}
void PokerGame::dealToEveryone(uint8_t count) {
void PokerGame::dealToEveryone(const uint8_t count) {
for(uint8_t i = 0; i < count; i++) {
auto it = this->players.begin();
while(it != this->players.end()) {
this->dealCard(*it);
this->dealCard(*(*it));
++it;
}
}
}
void PokerGame::turn(uint8_t count) {
assertTrue(this->deck.size() >= count);
void PokerGame::turn(const uint8_t count) {
assertTrue(this->deck.size() >= count, "Not enough cards to turn.");
for(uint8_t i = 0; i < count; i++) {
auto card = this->deck.back();
this->deck.pop_back();

View File

@ -21,7 +21,6 @@ namespace Dawn {
protected:
std::vector<struct Card> deck;
std::vector<struct Card> grave;
std::vector<struct Card> community;
uint8_t dealerIndex;
uint8_t smallBlindIndex;
uint8_t bigBlindIndex;
@ -29,25 +28,101 @@ namespace Dawn {
int32_t bigBlind = POKER_BLIND_BIG_DEFAULT;
public:
std::vector<PokerPlayer*> players;
std::vector<std::shared_ptr<PokerPlayer>> players;
std::vector<struct PokerPot> pots;
std::vector<struct Card> community;
uint8_t betterIndex;
/**
* Starts a new game of poker.
*/
void newGame();
/**
* Starts a new round of poker.
*/
void newRound();
/**
* Starts a new betting round.
*/
void newBettingRound();
/**
* Takes the blinds from the players.
*/
void takeBlinds();
void setBlinds(int32_t small, int32_t big);
/**
* Sets the blinds for the game.
*
* @param small The cost of the small blind.
* @param big The cost of the big blind.
*/
void setBlinds(const int32_t small, const int32_t big);
/**
* Returns the count of players that still need to bet this round.
*
* @return The count of players that still need to bet this round.
*/
uint8_t getRemainingBettersCount();
/**
* Returns the current call value for the game.
*
* @return The current call value for the game.
*/
int32_t getCurrentCallValue();
/**
* Returns the next better index.
*
* @return The next better index.
*/
uint8_t getNextBetterIndex();
void setDealer(uint8_t dealer);
void newDealer();
/**
* Sets the dealer for the game.
*
* @param dealer The index of the dealer.
*/
void setDealer(const uint8_t dealer);
/**
* Sends a card to the burn pile.
*/
void burnCard();
void dealCard(PokerPlayer *player);
void dealToEveryone(uint8_t count);
void turn(uint8_t count);
/**
* Deals a card to a player.
*
* @param player The player to deal the card to.
*/
void dealCard(PokerPlayer &player);
/**
* Deals a card to each player.
*/
void dealToEveryone(const uint8_t count);
/**
* Deals a card to the community.
*/
void turn(const uint8_t count);
/**
* Returns the count of cards that need to be turned.
*
* @return The count of cards that need to be turned.
*/
uint8_t getCountOfCardsToTurn();
/**
* Returns the count of players that are still in the game.
*
* @return The count of players that are still in the game.
*/
uint8_t getRemainingPlayersCount();
};
}

View File

@ -6,6 +6,8 @@
#include "PokerPlayer.hpp"
#include "PokerGame.hpp"
#include "util/Math.hpp"
#include "util/Random.hpp"
#include "util/Easing.hpp"
using namespace Dawn;
@ -42,7 +44,6 @@ void PokerPlayer::bet(
struct PokerPot &pot,
const int32_t chips
) {
assertNotNull(pot, "Pot must be valid.");
assertTrue(chips >= 0, "Chips must be a positive value.");
assertTrue(!this->isFolded, "Cannot bet if player is folded.");
assertTrue(!this->isOut, "Cannot bet if player is out.");
@ -68,7 +69,7 @@ void PokerPlayer::bet(const int32_t chips) {
assertNotNull(pg, "PokerGame has become invalid.");
assertTrue(pg->pots.size() > 0, "PokerGame has no pots?");
assertUnreachable("Bugged");
// this->bet(&this->pokerGame->pots.back(), chips);
this->bet(pg->pots.back(), chips);
}
void PokerPlayer::fold() {
@ -92,6 +93,9 @@ struct PokerTurn PokerPlayer::getAITurn() {
int32_t callBet;
float_t potOdds;
auto pg = this->pokerGame.lock();
assertNotNull(pg, "PokerGame has become invalid.");
// Can the player do anything?
if(this->isFolded || this->isOut) {
turn.type = POKER_TURN_TYPE_OUT;
@ -107,8 +111,11 @@ struct PokerTurn PokerPlayer::getAITurn() {
// Is this preflop?
if(this->pokerGame->community.size() == 0) {
assertTrue(this->hand.size() == POKER_PLAYER_HAND_SIZE_MAX);
if(pg->community.size() == 0) {
assertTrue(
this->hand.size() == POKER_PLAYER_HAND_SIZE_MAX,
"Invalid hand size."
);
// Get the hand weight
auto cardNumber0 = this->hand[0].getValue();
@ -117,7 +124,7 @@ struct PokerTurn PokerPlayer::getAITurn() {
auto suitNumber1 = this->hand[1].getSuit();
// Get delta between cards
auto i = (uint8_t)mathAbs<int8_t>(
auto i = (uint8_t)Math::abs<int8_t>(
(int8_t)cardNumber0 - (int8_t)cardNumber1
);
@ -142,7 +149,7 @@ struct PokerTurn PokerPlayer::getAITurn() {
// This may change in future, but I was finding the AI did not want to bet
// during the preflop enough, this curves the AI to want to preflop call
// often.
confidence = easeOutCubic(confidence);
confidence = Easing::easeOutCubic(confidence);
} else {
// Simulate my hand being the winning hand, use that as the confidence
auto winning = this->getWinning();
@ -160,14 +167,14 @@ struct PokerTurn PokerPlayer::getAITurn() {
(float_t)this->getSumOfChips()
);
} else {
potOdds = 1.0f / (float_t)this->pokerGame->getRemainingBettersCount();
potOdds = 1.0f / (float_t)pg->getRemainingBettersCount();
}
// Now determine the expected ROI
auto expectedGain = confidence / potOdds;
// Now get a random 0-100
auto random = randomGenerate<int32_t>() % 100;
auto random = Random::random<int32_t>() % 100;
// Determine the max bet that the AI is willing to make
auto maxBet = (int32_t)((float_t)this->chips / 1.75f) - (random / 2);
@ -206,7 +213,7 @@ struct PokerTurn PokerPlayer::getAITurn() {
} else {
amount = maxBet;
}
} else if(confidence < 0.95f || this->pokerGame->community.size() < 4) {
} else if(confidence < 0.95f || pg->community.size() < 4) {
if(random < 20) {
amount = callBet;
} else {
@ -220,7 +227,7 @@ struct PokerTurn PokerPlayer::getAITurn() {
// number.
// If this is the first round... make it a lot less likely I'll bet
if(this->pokerGame->community.size() == 0 && amount > callBet) {
if(pg->community.size() == 0 && amount > callBet) {
if(random > 5) amount = callBet;
}
@ -233,7 +240,7 @@ struct PokerTurn PokerPlayer::getAITurn() {
amount = callBet;
}
amount = mathMax<int32_t>(amount, callBet);
amount = Math::max<int32_t>(amount, callBet);
turn = PokerTurn::bet(this, amount);
turn.confidence = confidence;
} else if(this->canCheck()) {
@ -248,13 +255,17 @@ struct PokerTurn PokerPlayer::getAITurn() {
}
int32_t PokerPlayer::getCallBet() {
return this->pokerGame->getCurrentCallValue() - this->currentBet;
auto pg = this->pokerGame.lock();
assertNotNull(pg, "PokerGame has become invalid.");
return pg->getCurrentCallValue() - this->currentBet;
}
int32_t PokerPlayer::getSumOfChips() {
auto pg = this->pokerGame.lock();
assertNotNull(pg, "PokerGame has become invalid.");
int32_t count = 0;
auto it = this->pokerGame->pots.begin();
while(it != this->pokerGame->pots.end()) {
auto it = pg->pots.begin();
while(it != pg->pots.end()) {
if(std::find(it->players.begin(), it->players.end(), this) != it->players.end()) {
count += it->chips;
}
@ -272,16 +283,19 @@ struct PokerWinning PokerPlayer::getWinning() {
enum CardSuit suit;
std::vector<struct Card> pairs;
winning.player = this;
auto pg = this->pokerGame.lock();
assertNotNull(pg, "PokerGame has become invalid.");
winning.player = shared_from_this();
// Get the full poker hand (should be a 7 card hand, but MAY not be)
for(i = 0; i < this->pokerGame->community.size(); i++) {
winning.full.push_back(this->pokerGame->community[i]);
for(i = 0; i < pg->community.size(); i++) {
winning.full.push_back(pg->community[i]);
}
for(i = 0; i < this->hand.size(); i++) {
winning.full.push_back(this->hand[i]);
}
Card::sort(&winning.full);
Card::sort(winning.full);
//////////////////////// Now look for the winning set ////////////////////////
@ -289,7 +303,7 @@ struct PokerWinning PokerPlayer::getWinning() {
for(i = 0; i < winning.full.size(); i++) {
card = winning.full[i];
number = card.getValue();
if(number < CARD_FIVE) continue;
if(number < CardValue::Five) continue;
suit = card.getSuit();
@ -300,11 +314,11 @@ struct PokerWinning PokerPlayer::getWinning() {
for(j = 1; j <= 4; j++) {
// Ace low.
look = (
number == CARD_FIVE && j == 4 ?
(enum CardValue)CARD_ACE :
(enum CardValue)(number - j)
number == CardValue::Five && j == 4 ?
(enum CardValue)CardValue::Ace :
(enum CardValue)((uint8_t)number - j)
);
index = Card::contains(&winning.full, Card(suit, look));
index = Card::contains(winning.full, Card(suit, look));
if(index == -1) break;
winning.set.push_back(winning.full[index]);
}
@ -314,8 +328,8 @@ struct PokerWinning PokerPlayer::getWinning() {
// Add self to array
winning.type = (
number == CARD_ACE ? POKER_WINNING_TYPE_ROYAL_FLUSH :
POKER_WINNING_TYPE_STRAIGHT_FLUSH
number == CardValue::Ace ? PokerWinningType::RoyalFlush :
PokerWinningType::StraightFlush
);
winning.fillRemaining();
return winning;
@ -325,11 +339,11 @@ struct PokerWinning PokerPlayer::getWinning() {
for(i = 0; i < winning.full.size(); i++) {
card = winning.full[i];
number = card.getValue();
pairs = Card::countPairs(&winning.full, number);
pairs = Card::countPairs(winning.full, number);
if(pairs.size() < CARD_SUIT_COUNT) continue;
winning.set = pairs;
winning.type = POKER_WINNING_TYPE_FOUR_OF_A_KIND;
winning.type = PokerWinningType::FourOfAKind;
winning.fillRemaining();
return winning;
}
@ -339,12 +353,12 @@ struct PokerWinning PokerPlayer::getWinning() {
for(i = 0; i < winning.full.size(); i++) {
// Check we haven't already added this card.
card = winning.full[i];
if(Card::contains(&winning.set, card) != -1) {
if(Card::contains(winning.set, card) != -1) {
continue;
}
number = card.getValue();
pairs = Card::countPairs(&winning.full, number);
pairs = Card::countPairs(winning.full, number);
// Did we find either two pair or three pair?
if(pairs.size() != 2 && pairs.size() != 3) continue;
@ -359,7 +373,7 @@ struct PokerWinning PokerPlayer::getWinning() {
// Winned?
if(winning.set.size() != POKER_WINNING_SET_SIZE) continue;
winning.type = POKER_WINNING_TYPE_FULL_HOUSE;
winning.type = PokerWinningType::FullHouse;
winning.fillRemaining();
return winning;
}
@ -378,7 +392,7 @@ struct PokerWinning PokerPlayer::getWinning() {
if(winning.set.size() == POKER_WINNING_SET_SIZE) break;
}
if(winning.set.size() < POKER_WINNING_SET_SIZE) continue;
winning.type = POKER_WINNING_TYPE_FLUSH;
winning.type = PokerWinningType::Flush;
winning.fillRemaining();
return winning;
}
@ -387,7 +401,7 @@ struct PokerWinning PokerPlayer::getWinning() {
for(i = 0; i < winning.full.size(); i++) {
card = winning.full[i];
number = card.getValue();
if(number < CARD_FIVE) continue;
if(number < CardValue::Five) continue;
winning.set.clear();
winning.set.push_back(card);
@ -395,18 +409,18 @@ struct PokerWinning PokerPlayer::getWinning() {
for(j = 1; j <= 4; j++) {
// Ace low.
look = (
number == CARD_FIVE && j == 4 ?
(enum CardValue)CARD_ACE :
(enum CardValue)(number - j)
number == CardValue::Five && j == 4 ?
(enum CardValue)CardValue::Ace :
(enum CardValue)((uint8_t)number - j)
);
index = Card::containsNumber(&winning.full, look);
index = Card::containsValue(winning.full, look);
if(index == -1) break;
winning.set.push_back(winning.full[index]);
}
// Check if has all necessary cards.
if(winning.set.size() < POKER_WINNING_SET_SIZE) continue;
winning.type = POKER_WINNING_TYPE_STRAIGHT;
winning.type = PokerWinningType::Straight;
winning.fillRemaining();
return winning;
}
@ -415,11 +429,11 @@ struct PokerWinning PokerPlayer::getWinning() {
for(i = 0; i < winning.full.size(); i++) {
card = winning.full[i];
number = card.getValue();
pairs = Card::countPairs(&winning.full, number);
pairs = Card::countPairs(winning.full, number);
if(pairs.size() != 3) continue;
winning.set = pairs;
winning.type = POKER_WINNING_TYPE_THREE_OF_A_KIND;
winning.type = PokerWinningType::ThreeOfAKind;
winning.fillRemaining();
return winning;
}
@ -430,26 +444,26 @@ struct PokerWinning PokerPlayer::getWinning() {
card = winning.full[i];// Check we haven't already added this card.
if(
winning.set.size() > 0 &&
Card::contains(&winning.set, card) != -1
Card::contains(winning.set, card) != -1
) {
continue;
}
number = card.getValue();
pairs = Card::countPairs(&winning.full, number);
pairs = Card::countPairs(winning.full, number);
if(pairs.size() != 2) continue;
for(j = 0; j < pairs.size(); j++) {
winning.set.push_back(pairs[j]);
}
if(winning.set.size() != 4) continue;
winning.type = POKER_WINNING_TYPE_TWO_PAIR;
winning.type = PokerWinningType::TwoPair;
winning.fillRemaining();
return winning;
}
// Pair
if(winning.set.size() == 2) {
winning.type = POKER_WINNING_TYPE_PAIR;
winning.type = PokerWinningType::Pair;
winning.fillRemaining();
return winning;
}
@ -457,6 +471,6 @@ struct PokerWinning PokerPlayer::getWinning() {
// High card
winning.set.clear();
winning.fillRemaining();
winning.type = POKER_WINNING_TYPE_HIGH_CARD;
winning.type = PokerWinningType::HighCard;
return winning;
}

View File

@ -20,7 +20,7 @@
namespace Dawn {
class PokerGame;
class PokerPlayer {
class PokerPlayer : public std::enable_shared_from_this<PokerPlayer> {
public:
std::weak_ptr<PokerGame> pokerGame;
int32_t chips = 0;
@ -69,7 +69,7 @@ namespace Dawn {
* @param pot Poker pot to bet in to.
* @param amount The amount of chips the player is betting.
*/
void bet(struct PokerPot pot, const int32_t amount);
void bet(struct PokerPot &pot, const int32_t amount);
/**
* Let a player bet chips into the current pot.

View File

@ -21,7 +21,7 @@ void PokerPotWinning::award() {
}
}
struct PokerPotWinning PokerPot::getWinners(PokerGame *game) {
struct PokerPotWinning PokerPot::getWinners() {
struct PokerPotWinning winning;
winning.pot = this;
@ -47,8 +47,8 @@ struct PokerPotWinning PokerPot::getWinners(PokerGame *game) {
auto playerLeft = *it2;
auto winnerLeft = &winning.winnings[playerLeft];
bool_t isWinner = true;
enum CardValue highNumber = CARD_VALUE_INVALD;
enum CardValue number = CARD_VALUE_INVALD;
enum CardValue highNumber = CardValue::Invalid;
enum CardValue number = CardValue::Invalid;
struct Card highCard(0xFF);
struct Card card(0xFF);
@ -82,8 +82,8 @@ struct PokerPotWinning PokerPot::getWinners(PokerGame *game) {
// Determine high card.
number = card.getValue();
if(
highNumber == CARD_VALUE_INVALD ||
number == CARD_ACE ||
highNumber == CardValue::Invalid ||
number == CardValue::Ace ||
number > highNumber
) {
highCard = card;

View File

@ -13,9 +13,9 @@ namespace Dawn {
struct PokerPotWinning {
public:
std::map<PokerPlayer*,struct PokerWinning> winnings;
std::vector<PokerPlayer*> winners;
std::vector<PokerPlayer*> participants;
std::map<std::shared_ptr<PokerPlayer>, struct PokerWinning> winnings;
std::vector<std::shared_ptr<PokerPlayer>> winners;
std::vector<std::shared_ptr<PokerPlayer>> participants;
struct PokerPot *pot;
int32_t chipsEach;
int32_t chipsOverflow;
@ -27,8 +27,13 @@ namespace Dawn {
public:
int32_t chips;
int32_t call;
std::vector<PokerPlayer*> players;
std::vector<std::shared_ptr<PokerPlayer>> players;
struct PokerPotWinning getWinners(PokerGame *game);
/**
* Get the winners of the pot.
*
* @return The winning state of the pot.
*/
struct PokerPotWinning getWinners();
};
}

View File

@ -10,23 +10,23 @@ using namespace Dawn;
float_t PokerWinning::getWinningTypeConfidence(enum PokerWinningType type) {
switch(type) {
case POKER_WINNING_TYPE_ROYAL_FLUSH:
case PokerWinningType::RoyalFlush:
return POKER_WINNING_CONFIDENCE_ROYAL_FLUSH;
case POKER_WINNING_TYPE_STRAIGHT_FLUSH:
case PokerWinningType::StraightFlush:
return POKER_WINNING_CONFIDENCE_STRAIGHT_FLUSH;
case POKER_WINNING_TYPE_FOUR_OF_A_KIND:
case PokerWinningType::FourOfAKind:
return POKER_WINNING_CONFIDENCE_FOUR_OF_A_KIND;
case POKER_WINNING_TYPE_FULL_HOUSE:
case PokerWinningType::FullHouse:
return POKER_WINNING_CONFIDENCE_FULL_HOUSE;
case POKER_WINNING_TYPE_FLUSH:
case PokerWinningType::Flush:
return POKER_WINNING_CONFIDENCE_FLUSH;
case POKER_WINNING_TYPE_STRAIGHT:
case PokerWinningType::Straight:
return POKER_WINNING_CONFIDENCE_STRAIGHT;
case POKER_WINNING_TYPE_THREE_OF_A_KIND:
case PokerWinningType::ThreeOfAKind:
return POKER_WINNING_CONFIDENCE_THREE_OF_A_KIND;
case POKER_WINNING_TYPE_TWO_PAIR:
case PokerWinningType::TwoPair:
return POKER_WINNING_CONFIDENCE_TWO_PAIR;
case POKER_WINNING_TYPE_PAIR:
case PokerWinningType::Pair:
return POKER_WINNING_CONFIDENCE_PAIR;
default:
return POKER_WINNING_CONFIDENCE_HIGH_CARD;
@ -34,34 +34,31 @@ float_t PokerWinning::getWinningTypeConfidence(enum PokerWinningType type) {
}
struct Card PokerWinning::compare(
struct PokerWinning *left,
struct PokerWinning *right
const struct PokerWinning &left,
const struct PokerWinning &right
) {
assertNotNull(left);
assertNotNull(right);
uint8_t i;
enum CardValue number = CARD_VALUE_INVALD;
enum CardValue highNumberLeft = CARD_VALUE_INVALD;
enum CardValue highNumberRight = CARD_VALUE_INVALD;
enum CardValue number = CardValue::Invalid;
enum CardValue highNumberLeft = CardValue::Invalid;
enum CardValue highNumberRight = CardValue::Invalid;
struct Card card(0xFF), highCardLeft(0xFF), highCardRight(0xFF);
int32_t index;
uint8_t countCardsSame;
countCardsSame = 0;
for(i = 0; i < left->set.size(); i++) {
card = left->set[i];
for(i = 0; i < left.set.size(); i++) {
card = left.set[i];
number = card.getValue();
// Quick check
if(highNumberLeft != CARD_VALUE_INVALD && number < highNumberLeft) continue;
if(highNumberLeft != CardValue::Invalid && number < highNumberLeft) continue;
// Check if this number is within the other hand or not
index = Card::containsNumber(&right->set, number);
index = Card::containsValue(right.set, 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 = Card::contains(&right->set, card);
index = Card::contains(right.set, card);
// Exact card match
if(index != -1) {
@ -72,8 +69,8 @@ struct Card PokerWinning::compare(
}
if(
highNumberLeft == CARD_VALUE_INVALD ||
number == CARD_ACE ||
highNumberLeft == CardValue::Invalid ||
number == CardValue::Ace ||
highNumberLeft < number
) {
highNumberLeft = number;
@ -81,22 +78,22 @@ struct Card PokerWinning::compare(
}
}
for(i = 0; i < right->set.size(); i++) {
card = right->set[i];
for(i = 0; i < right.set.size(); i++) {
card = right.set[i];
number = card.getValue();
if(highNumberRight != CARD_VALUE_INVALD && number < highNumberRight) {
if(highNumberRight != CardValue::Invalid && number < highNumberRight) {
continue;
}
index = Card::containsNumber(&left->set, number);
index = Card::containsValue(left.set, number);
if(index != -1) {
index = Card::contains(&left->set, card);
index = Card::contains(left.set, card);
if(index != -1) continue;
}
if(
highNumberRight == CARD_VALUE_INVALD ||
number == CARD_ACE || highNumberRight < number
highNumberRight == CardValue::Invalid ||
number == CardValue::Ace || highNumberRight < number
) {
highNumberRight = number;
highCardRight = card;
@ -104,13 +101,13 @@ struct Card PokerWinning::compare(
}
if(countCardsSame == left->set.size()) {
for(i = 0; i < left->set.size(); i++) {
card = left->set[i];
if(countCardsSame == left.set.size()) {
for(i = 0; i < left.set.size(); i++) {
card = left.set[i];
number = card.getValue();
if(
highNumberLeft == CARD_VALUE_INVALD ||
number == CARD_ACE ||
highNumberLeft == CardValue::Invalid ||
number == CardValue::Ace ||
highNumberLeft < number
) {
highNumberLeft = number;
@ -120,13 +117,14 @@ struct Card PokerWinning::compare(
return highCardLeft;
}
if(highCardLeft.cardValue == CARD_VALUE_INVALD) return 0xFF;
if(highCardLeft.cardValue == 0xFF) return 0xFF;
if(highNumberLeft < highNumberRight) return 0xFF;
return highCardLeft;// Greater or Equal to.
}
void PokerWinning::fillRemaining() {
uint8_t i, highest, current;
uint8_t i;
CardValue highest, current;
struct Card highestCard(0x00);
struct Card currentCard(0x00);
@ -135,25 +133,25 @@ void PokerWinning::fillRemaining() {
// Fill the remaining cards
while(this->set.size() < POKER_WINNING_SET_SIZE) {
highest = 0xFF;
highest = CardValue::Invalid;
for(i = 0; i < this->full.size(); i++) {
currentCard = this->full[i];
if(Card::contains(&this->set, currentCard) != -1) continue;
if(Card::contains(this->set, currentCard) != -1) continue;
if(highest == 0xFF) {
if(highest == CardValue::Invalid) {
highestCard = currentCard;
highest = highestCard.getValue();
} else {
current = currentCard.getValue();
if(current != CARD_ACE && current < highest) continue;
if(current != CardValue::Ace && current < highest) continue;
highestCard = currentCard;
highest = current;
}
}
if(highest == 0xFF) break;
if(highest == CardValue::Invalid) break;
this->set.push_back(highestCard);
}
Card::sort(&this->set);
Card::sort(this->set);
}

View File

@ -24,18 +24,18 @@
namespace Dawn {
class PokerPlayer;
enum PokerWinningType {
POKER_WINNING_TYPE_NULL,
POKER_WINNING_TYPE_ROYAL_FLUSH,
POKER_WINNING_TYPE_STRAIGHT_FLUSH,
POKER_WINNING_TYPE_FOUR_OF_A_KIND,
POKER_WINNING_TYPE_FULL_HOUSE,
POKER_WINNING_TYPE_FLUSH,
POKER_WINNING_TYPE_STRAIGHT,
POKER_WINNING_TYPE_THREE_OF_A_KIND,
POKER_WINNING_TYPE_TWO_PAIR,
POKER_WINNING_TYPE_PAIR,
POKER_WINNING_TYPE_HIGH_CARD
enum class PokerWinningType {
Null,
RoyalFlush,
StraightFlush,
FourOfAKind,
FullHouse,
Flush,
Straight,
ThreeOfAKind,
TwoPair,
Pair,
HighCard
};
struct PokerWinning {
@ -57,8 +57,8 @@ namespace Dawn {
* @return The kicker card from left's hand or 0xFF if not the winner.
*/
static struct Card compare(
struct PokerWinning *left,
struct PokerWinning *right
const struct PokerWinning &left,
const struct PokerWinning &right
);
/** Winning Type */
@ -70,7 +70,7 @@ namespace Dawn {
/** If there was a kicker card it will be here */
struct Card kicker;
/* The player this winning state belongs to */
PokerPlayer *player;
std::shared_ptr<PokerPlayer> player;
PokerWinning() : kicker(0xFF) {}