Working on poker logic.

This commit is contained in:
2021-09-25 01:36:25 -07:00
parent 425faff720
commit 914741c175
7 changed files with 222 additions and 74 deletions

View File

@ -116,20 +116,24 @@ void _pokerGameActionBetOnEnd(
// Not waiting, restack and do next action.
printf("Not waiting on anything!\n");
// No! Begin the next flop.
next = pokerActionNextFlopAdd(queue, &game->poker);
if(next != NULL) {
discussion.reason = POKER_DISCUSSION_REASON_FLOP;
pokerDiscussionQueue(&discussion);
// Is there a next round, or did someone just win?
if(pokerBetGetRemainingPlayerCount(&game->poker.bet,game->poker.players) > 1){
// No! Begin the next flop.
next = pokerActionNextFlopAdd(queue, &game->poker);
if(next != NULL) {
discussion.reason = POKER_DISCUSSION_REASON_FLOP;
pokerDiscussionQueue(&discussion);
pokerBetResetBetter(
&game->poker.bet, game->poker.players, game->poker.roundSmallBlind
);
pokerGameActionRestackAdd(game);
pokerGameActionLookAdd(game, game->poker.bet.better);
pokerGameActionBetAdd(game);
return;
pokerBetResetBetter(
&game->poker.bet, game->poker.players, game->poker.roundSmallBlind
);
pokerGameActionRestackAdd(game);
pokerGameActionLookAdd(game, game->poker.bet.better);
pokerGameActionBetAdd(game);
return;
}
}
// Done betting
printf("All betting is done, reveal\n");

View File

@ -42,8 +42,7 @@ void pokerBetResetBetter(
}
bool pokerBetPlayerCanBet(pokerbet_t *bet, pokerplayer_t *player) {
if((player->state & POKER_PLAYER_STATE_FOLDED) != 0) return false;
if(player->state & POKER_PLAYER_STATE_OUT) return false;
if(!pokerPlayerIsAlive(player)) return false;
if(player->state & POKER_PLAYER_STATE_ROUND_MOVE) {
if(player->currentBet >= bet->currentBet && player) return false;
}
@ -63,6 +62,16 @@ uint8_t pokerBetGetRemainingPlayer(
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(!pokerPlayerIsAlive(players + i)) continue;
c++;
}
return c;
}
void pokerBetTakeBlinds(
pokerbet_t *bet, pokerplayer_t *players,
uint8_t roundSmallBlind, uint8_t roundBigBlind

View File

@ -96,6 +96,16 @@ uint8_t pokerBetGetRemainingPlayer(
pokerbet_t *bet, pokerplayer_t *players, uint8_t roundSmallBlind
);
/**
* Returns the count of players who are still available to bet. This does not
* consider any round logic, simply whether or not they COULD bet.
*
* @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.
*

View File

@ -9,7 +9,12 @@
pokerturn_t pokerTurnGet(poker_t *poker, uint8_t playerIndex) {
pokerplayer_t *player;
float confidence;
float t, confidence, cardWeight, handWeight;
float betWeight, potWeight, inWeight, roundWeight, bet;
card_t bestCard;
uint8_t i, bestCardNumber;
int32_t chips;
player = poker->players + playerIndex;
// Can the player do anything?
@ -26,45 +31,86 @@ pokerturn_t pokerTurnGet(poker_t *poker, uint8_t playerIndex) {
pokerplayerwinning_t winning;
pokerWinnerPlayerGet(&poker->dealer, player, &winning);
// Now let's determine the "base confidence". This is basically how good the
// hand is relative to a completely equal footing/player field.
switch(winning.type) {
case POKER_WINNING_TYPE_ROYAL_FLUSH:
confidence = POKER_TURN_CONFIDENCE_ROYAL_FLUSH;
break;
case POKER_WINNING_TYPE_STRAIGHT_FLUSH:
confidence = POKER_TURN_CONFIDENCE_STRAIGHT_FLUSH;
break;
case POKER_WINNING_TYPE_FOUR_OF_A_KIND:
confidence = POKER_TURN_CONFIDENCE_FOUR_OF_A_KIND;
break;
case POKER_WINNING_TYPE_FULL_HOUSE:
confidence = POKER_TURN_CONFIDENCE_FULL_HOUSE;
break;
case POKER_WINNING_TYPE_FLUSH:
confidence = POKER_TURN_CONFIDENCE_FLUSH;
break;
case POKER_WINNING_TYPE_STRAIGHT:
confidence = POKER_TURN_CONFIDENCE_STRAIGHT;
break;
case POKER_WINNING_TYPE_THREE_OF_A_KIND:
confidence = POKER_TURN_CONFIDENCE_THREE_OF_A_KIND;
break;
case POKER_WINNING_TYPE_TWO_PAIR:
confidence = POKER_TURN_CONFIDENCE_TWO_PAIR;
break;
case POKER_WINNING_TYPE_PAIR:
confidence = POKER_TURN_CONFIDENCE_PAIR;
break;
default:
confidence = POKER_TURN_CONFIDENCE_HIGH_CARD;
break;
// Now try and figure out how good the hand is
handWeight = 0;
for(i = 0; i < winning.setSize; i++) {
bestCard = winning.set[i];
handWeight += pokerWinnerGetCardWeight(bestCard);
}
// Now we have a base confidence, let's figure out how good our hand is based
// on our high card. This will decide whether or not our hand is as strong as
// it seems on its base level
handWeight = handWeight / winning.setSize;
bestCard = pokerWinnerGetBestCard(winning.set, winning.setSize);
bestCardNumber = cardGetNumber(bestCard);
confidence = pokerWinnerGetTypeConfidence(winning.type);
cardWeight = pokerWinnerGetCardWeight(bestCard);
// Now figure out what the risk of betting is.
inWeight = (float)player->currentBet / (float)player->chips;
roundWeight = (
((float)poker->dealer.cardsFacing) / ((float)POKER_DEALER_HAND_SIZE)
);
betWeight = (float)(
poker->bet.currentBet - player->currentBet
) / (float)player->chips;
potWeight = poker->bet.pot / (float)player->chips;
// We now need to act on these values.
printf("Card Weights - %.4f, %.4f, %.4f, %.4f\n", confidence, cardWeight, handWeight);
printf("Money Weights - %.4f, %.4f, %.4f, %.4f\n", inWeight, roundWeight, betWeight, potWeight);
// Chip weight, 1 is all in.
bet = 0;
if(roundWeight == 0) {
// First Round
if(betWeight < 0.1) {
// The bet is "low risk" to me. (<10% of my chips), play a bit loose.
// Take any card with 70% weighting and/or any hand with a pair or better.
// if(cardWeight > 0.7 || confidence >= POKER_WINNNIG_CONFIDENCE_PAIR) {
// bet = confidence * 0.7f;
// } else if(cardWeight >= 0.5 && betWeight > 0) {
// }
bet = (1.0f - mathMin(betWeight*10, 0.5f)) * (cardWeight * confidence * 2.0f);
} else if(betWeight < 0.4) {
// Bet is "medium" risk to me (less than 40% of my chips)
// Bet on any hand that has a good chance.
if(confidence >= POKER_WINNNIG_CONFIDENCE_PAIR) {
bet = (confidence * mathMax(cardWeight, betWeight));
}
} else if(betWeight < 0.75) {
// Bet is "high" risk to me.
if(cardWeight > 0.6 && confidence >= POKER_WINNNIG_CONFIDENCE_PAIR) {
bet = (confidence * cardWeight);
}
} else {
// Bet is likely my last hand
}
} else {
// Not first round.
if(confidence <= POKER_WINNNIG_CONFIDENCE_PAIR) {
bet = (confidence * cardWeight) / betWeight;
} else if(confidence <= POKER_WINNNIG_CONFIDENCE_THREE_OF_A_KIND) {
bet = (confidence * (cardWeight / handWeight)) / betWeight;
} else {
bet = confidence * (cardWeight / handWeight) * 2;
}
}
printf("Bet %.4f\n\n", bet);
// Now determine chips based on bet.
if(bet >= 0.75) {
chips = (int32_t)(bet * (float)player->chips);
chips = mathMin(chips, player->chips);
return pokerTurnRaise(poker, playerIndex, chips);
} else if(bet >= 0.25f) {
return pokerTurnCall(poker, playerIndex);
}
// Well, now they have decided to "not bet", or really they think that their
// cards are not worth the effort. But if they CAN check, they will.
if(pokerTurnCanPlayerCheck(poker, playerIndex)) {
@ -120,11 +166,6 @@ pokerturn_t pokerTurnCall(poker_t *poker, uint8_t playerIndex) {
turn = pokerTurnRaise(
poker, playerIndex, poker->bet.currentBet - player->currentBet
);
turn.type = (
turn.type == POKER_TURN_TYPE_ALL_IN ?
POKER_TURN_TYPE_CALL_ALL_IN :
POKER_TURN_TYPE_CALL
);
return turn;
}
@ -133,12 +174,22 @@ pokerturn_t pokerTurnRaise(poker_t *poker, uint8_t playerIndex, int32_t chips) {
pokerplayer_t *player;
player = poker->players + playerIndex;
if(chips < poker->bet.currentBet) chips = poker->bet.currentBet;
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) {
turn.type = POKER_TURN_TYPE_CALL;
}
if(chips == 0) {
turn.type = POKER_TURN_TYPE_CALL;
}
}
return turn;

View File

@ -8,6 +8,7 @@
#pragma once
#include "../libs.h"
#include "poker.h"
#include "winner.h"
#define POKER_TURN_TYPE_OUT 0x00
#define POKER_TURN_TYPE_FOLD 0x01
@ -17,17 +18,6 @@
#define POKER_TURN_TYPE_CALL_ALL_IN 0x04
#define POKER_TURN_TYPE_CHECK 0x05
#define POKER_TURN_CONFIDENCE_ROYAL_FLUSH 1.0f
#define POKER_TURN_CONFIDENCE_STRAIGHT_FLUSH 0.9f
#define POKER_TURN_CONFIDENCE_FOUR_OF_A_KIND 0.85f
#define POKER_TURN_CONFIDENCE_FULL_HOUSE 0.83f
#define POKER_TURN_CONFIDENCE_FLUSH 0.8f
#define POKER_TURN_CONFIDENCE_STRAIGHT 0.75f
#define POKER_TURN_CONFIDENCE_THREE_OF_A_KIND 0.75f
#define POKER_TURN_CONFIDENCE_TWO_PAIR 0.7f
#define POKER_TURN_CONFIDENCE_PAIR 0.6f
#define POKER_TURN_CONFIDENCE_HIGH_CARD 0.5f
/** The turn that a player/the AI decided to do for its turn */
typedef struct {
/** What type of action the turn is */

View File

@ -7,10 +7,6 @@
#include "winner.h"
void pokerWinnerGetBestCard(card_t *cards, uint8_t cardCount) {
}
void pokerWinnerHandGetFull(
pokerdealer_t *dealer, pokerplayer_t *player, card_t *cards
) {
@ -242,6 +238,7 @@ void _pokerWinnerFillRemaining(pokerplayerwinning_t *winning) {
}
}
if(highest == 0xFF) break;
winning->set[winning->setSize++] = highestCard;
}
cardHandSort(winning->set, winning->setSize);
@ -385,3 +382,53 @@ void pokerWinnerCalculate(
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);
}

View File

@ -18,7 +18,7 @@
/** How many cards make a winning set */
#define POKER_WINNING_SET_SIZE 5
/** Winning Types */
/** Winning Types */
#define POKER_WINNING_TYPE_NULL 0x00
#define POKER_WINNING_TYPE_ROYAL_FLUSH 0x01
#define POKER_WINNING_TYPE_STRAIGHT_FLUSH 0x02
@ -31,6 +31,17 @@
#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.9f
#define POKER_WINNNIG_CONFIDENCE_FOUR_OF_A_KIND 0.85f
#define POKER_WINNNIG_CONFIDENCE_FULL_HOUSE 0.83f
#define POKER_WINNNIG_CONFIDENCE_FLUSH 0.8f
#define POKER_WINNNIG_CONFIDENCE_STRAIGHT 0.75f
#define POKER_WINNNIG_CONFIDENCE_THREE_OF_A_KIND 0.75f
#define POKER_WINNNIG_CONFIDENCE_TWO_PAIR 0.7f
#define POKER_WINNNIG_CONFIDENCE_PAIR 0.6f
#define POKER_WINNNIG_CONFIDENCE_HIGH_CARD 0.5f
/** Holds information about a player's winning state */
typedef struct {
/** The full set of both the dealer and player's hand */
@ -108,4 +119,30 @@ card_t pokerWinnerCompare(
*/
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);