Working on restoring betting code.
This commit is contained in:
@ -188,6 +188,7 @@ bool pokerPlayerDoesNeedToBetThisRound(poker_t *poker, uint8_t playerIndex) {
|
||||
pokerplayer_t *player;
|
||||
player = poker->players + playerIndex;
|
||||
if(player->state & POKER_PLAYER_STATE_FOLDED) return false;
|
||||
if(player->chips <= 0) return false;
|
||||
if(!(player->state & POKER_PLAYER_STATE_HAS_BET_THIS_ROUND)) return true;
|
||||
if(player->currentBet < pokerGetCallValue(poker)) return true;
|
||||
return false;
|
||||
@ -233,6 +234,16 @@ uint8_t pokerInRoundGetCount(poker_t *poker) {
|
||||
return count;
|
||||
}
|
||||
|
||||
uint8_t pokerPlayerGetRemainingBetterCount(poker_t *poker) {
|
||||
uint8_t i, count;
|
||||
count = 0;
|
||||
for(i = 0; i < poker->playerCount; i++) {
|
||||
if(!pokerPlayerDoesNeedToBetThisRound(poker, i)) continue;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// Betting
|
||||
void pokerPlayerBetPot(
|
||||
poker_t *poker, pokerpot_t *pot, uint8_t playerIndex, int32_t chips
|
||||
@ -290,6 +301,160 @@ pokerturn_t pokerTurnBet(poker_t *poker, uint8_t playerIndex, int32_t chips) {
|
||||
return turn;
|
||||
}
|
||||
|
||||
pokerturn_t pokerTurnGetForPlayer(poker_t *poker, uint8_t playerIndex) {
|
||||
int32_t random, maxBet, bluffBet, callBet;
|
||||
float confidence, expectedGain, potOdds;
|
||||
bool isBluff;
|
||||
int32_t amount;
|
||||
pokerplayer_t *player;
|
||||
pokerplayerwinning_t winning;
|
||||
uint8_t i, cardNumber0, cardNumber1, suitNumber0, suitNumber1;
|
||||
pokerturn_t turn;
|
||||
|
||||
player = poker->players + playerIndex;
|
||||
|
||||
// Can the player do anything?
|
||||
if(player->state & (POKER_PLAYER_STATE_FOLDED | POKER_PLAYER_STATE_OUT)) {
|
||||
turn.type = POKER_TURN_TYPE_OUT;
|
||||
return turn;
|
||||
}
|
||||
|
||||
// The following logic is heavily inspired by;
|
||||
// https://github.com/gorel/C-Poker-AI/blob/master/src/common/pokerai.c
|
||||
// But with some changes and smarts added by me. The original source code will
|
||||
// essentially just run a crap tun of simulated games and get the times that
|
||||
// they are expected to win from those games, but I'm just going to use the
|
||||
// odds of the winning hand.
|
||||
|
||||
// Is this preflop?
|
||||
if(poker->communitySize == 0 && player->cardCount >= 2) {
|
||||
// Get the hand weight
|
||||
cardNumber0 = cardGetNumber(player->cards[0]);
|
||||
cardNumber1 = cardGetNumber(player->cards[1]);
|
||||
suitNumber0 = cardGetSuit(player->cards[0]);
|
||||
suitNumber1 = cardGetSuit(player->cards[1]);
|
||||
|
||||
// Get delta between cards
|
||||
i = mathAbs(cardNumber0 - cardNumber1);
|
||||
|
||||
// Get card weight
|
||||
confidence = (float)cardNumber0 + (float)cardNumber1;
|
||||
if(cardNumber0 == cardNumber1) {// Pairs
|
||||
confidence += 6;
|
||||
} else if(suitNumber0 == suitNumber1) {// Same suit
|
||||
confidence += 4;
|
||||
}
|
||||
|
||||
// Get difference from cards for guessing flush
|
||||
if(i > 4) {
|
||||
confidence -= 4;
|
||||
} else if(i > 2) {
|
||||
confidence -= i;
|
||||
}
|
||||
|
||||
// Get the confidence delta 0-1
|
||||
confidence = confidence / 30.0f;
|
||||
} else {
|
||||
// Simulate my hand being the winning hand, use that as the confidence
|
||||
// pokerWinnerPlayerGet(&poker->community, player, &winning);
|
||||
// confidence = pokerWinnerGetTypeConfidence(winning.type);
|
||||
}
|
||||
|
||||
// Now we know how confident the AI is, let's put a chip value to that weight
|
||||
// How many chips to call?
|
||||
callBet = pokerPlayerGetCallBet(poker, player);
|
||||
|
||||
// Do they need chips to call, or is it possible to check?
|
||||
// if(callBet > 0) {
|
||||
// potOdds = (float)callBet / ((float)callBet + (float)poker->bet.pot);
|
||||
// } else {
|
||||
// potOdds = (
|
||||
// 1.0f / (float)pokerBetGetRemainingPlayerCount(&poker->bet, poker->players)
|
||||
// );
|
||||
// }
|
||||
|
||||
// Now determine the expected ROI
|
||||
expectedGain = confidence / potOdds;
|
||||
|
||||
// Now get a random 0-100
|
||||
random = randInt32() % 100;
|
||||
|
||||
// Determine the max bet that the AI is willing to make
|
||||
maxBet = (int32_t)((float)player->chips / 1.75f) - (random / 2);
|
||||
maxBet -= callBet;
|
||||
|
||||
// Determine what's a good bluff bet.
|
||||
bluffBet = random * maxBet / 100 / 2;
|
||||
|
||||
// Now prep the output
|
||||
isBluff = false;
|
||||
amount = 0;
|
||||
|
||||
// Now the actual AI can happen. This is basically a weight to confidence
|
||||
// ratio. The higher the gains and the confidence then the more likely the AI
|
||||
// is to betting. There are also bluff chances within here.
|
||||
if(expectedGain < 0.8 && confidence < 0.8) {
|
||||
if(random < 95) {
|
||||
amount = 0;
|
||||
} else {
|
||||
amount = bluffBet;
|
||||
isBluff = true;
|
||||
}
|
||||
} else if ((expectedGain < 1.0 && confidence < 0.85) || confidence < 0.1) {
|
||||
if (random < 80) {
|
||||
amount = 0;
|
||||
} else if(random < 5) {
|
||||
amount = callBet;
|
||||
isBluff = true;
|
||||
} else {
|
||||
amount = bluffBet;
|
||||
isBluff = true;
|
||||
}
|
||||
} else if ((expectedGain < 1.3 && confidence < 0.9) || confidence < 0.5) {
|
||||
if (random < 60 || confidence < 0.5) {
|
||||
amount = callBet;
|
||||
} else {
|
||||
amount = maxBet;
|
||||
}
|
||||
} else if (confidence < 0.95 || poker->communitySize < 0x04) {
|
||||
if(random < 20) {
|
||||
amount = callBet;
|
||||
} else {
|
||||
amount = maxBet;
|
||||
}
|
||||
} else {
|
||||
amount = (player->chips - callBet) * 9 / 10;
|
||||
}
|
||||
|
||||
// If this is the first round... make it a lot less likely I'll bet
|
||||
if(poker->communitySize == 0x00 && amount > callBet) {
|
||||
if(random > 5) amount = callBet;
|
||||
}
|
||||
|
||||
// Did we actually bet?
|
||||
// if(amount > 0) {
|
||||
// printf("AI is betting %i chips, bluff: %i\n", amount, isBluff);
|
||||
|
||||
// // Let's not get caught in a raising loop with AI.
|
||||
// if(player->timesRaised >= POKER_TURN_MAX_RAISES) {
|
||||
// amount = callBet;
|
||||
// }
|
||||
|
||||
// amount = mathMax(amount, callBet);
|
||||
// turn = pokerTurnRaise(poker, playerIndex, amount);
|
||||
// turn.confidence = confidence;
|
||||
// } else if(pokerTurnCanPlayerCheck(poker, playerIndex)) {
|
||||
// turn = pokerTurnCheck(poker, playerIndex);
|
||||
// turn.confidence = 1;
|
||||
// } else {
|
||||
// turn = pokerTurnFold(poker, playerIndex);
|
||||
// turn.confidence = 1 - confidence;
|
||||
// }
|
||||
|
||||
|
||||
return turn;
|
||||
}
|
||||
|
||||
// Winning
|
||||
void pokerHandGetFull(
|
||||
poker_t *poker, pokerplayer_t *player, card_t cards[POKER_WINNING_FULL_SIZE]
|
||||
|
@ -340,6 +340,14 @@ int32_t pokerPlayerGetCallBet(poker_t *poker, pokerplayer_t *player);
|
||||
*/
|
||||
uint8_t pokerInRoundGetCount(poker_t *poker);
|
||||
|
||||
/**
|
||||
* Returns the count of players remaining to bet.
|
||||
*
|
||||
* @param poker Poker game instance.
|
||||
* @return Count of players left to bet.
|
||||
*/
|
||||
uint8_t pokerPlayerGetRemainingBetterCount(poker_t *poker);
|
||||
|
||||
/**
|
||||
* Let a player bet chips into the pot.
|
||||
*
|
||||
@ -391,6 +399,15 @@ pokerturn_t pokerTurnFold(poker_t *poker, uint8_t player);
|
||||
*/
|
||||
pokerturn_t pokerTurnBet(poker_t *poker, uint8_t playerIndex, int32_t chips);
|
||||
|
||||
/**
|
||||
* Returns the AI result for a turn done by a non human player.
|
||||
*
|
||||
* @param poker Poker game instance to use.
|
||||
* @param playerIndex Player index to get the turn for.
|
||||
* @return Some information about the move the player is trying to perform.
|
||||
*/
|
||||
pokerturn_t pokerTurnGetForPlayer(poker_t *poker, uint8_t playerIndex);
|
||||
|
||||
/**
|
||||
* Returns the full hand for a given player including the best cards on the
|
||||
* bench.
|
||||
|
Reference in New Issue
Block a user