Working on poker logic.
This commit is contained in:
@ -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");
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
*
|
||||
|
137
src/poker/turn.c
137
src/poker/turn.c
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
@ -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);
|
Reference in New Issue
Block a user