Brought over unfinished ai code.

This commit is contained in:
2022-01-13 23:07:00 -08:00
parent 0cbc9a8d52
commit 31a6271f27
7 changed files with 219 additions and 53 deletions

View File

@@ -82,6 +82,7 @@ void pokerNewRound() {
POKER_PLAYER_STATE_FOLDED |
POKER_PLAYER_STATE_HAS_BET_THIS_ROUND
);
POKER_PLAYERS[i].timesRaised = 0;
// Have we found the dealer, small blind, and big blind players?
if(found != 3 && (POKER_PLAYERS[i].state & POKER_PLAYER_STATE_OUT) == 0){
@@ -137,14 +138,16 @@ inline void pokerBet(uint8_t player, uint16_t amount) {
inline uint8_t pokerGetCallBet(uint8_t player) {
return (
POKER_POTS[POKER_POT_CURRENT].call -
POKER_POTS[POKER_POT_CURRENT].players[POKER_PLAYER_BETTER]
POKER_POTS[POKER_POT_CURRENT].players[player]
);
}
void pokerAi(uint8_t player) {
void pokerAi(uint8_t player, pokerturn_t *turn) {
uint8_t i, cardNumber0, cardNumber1, suitNumber0, suitNumber1;
uint16_t callBet;
uint8_t confidence;// TODO: Determine type.
uint16_t callBet, maxBet, amount, bluffBet;
uint8_t random;// TODO: Determine type.
bool isBluff;
uint16_t confidence, expectedGain, potOdds;
pokerplayer_t *plyr = POKER_PLAYERS + player;
// The following logic is heavily inspired by;
@@ -180,12 +183,169 @@ void pokerAi(uint8_t player) {
} else if(i > 2) {
confidence -= i;
}
// Confidence is now a value between 0-30 (inclusive). Multiply by 1000
confidence = (confidence * 1000) / 30;
// Now do over 30 to get the value represented as 0-1000
} else {
// Simulate my hand being the winning hand, use that as the confidence
// TODO: Repurpose old code lmao. Just take it from Dawn-C
confidence = 0;
}
// Now we know how confident the AI is, let's put a chip value to that weight
// How many chips to call?
callBet = pokerGetCallBet(player);
// Do they need chips to call, or is it possible to check?
if(callBet > 0) {
// Work out how many chips the player could possibly win. This is a number
// between 0 and player count * initial chips, at the time of writing that
// is around 50,000.
expectedGain = 0;
for(i = 0; i < POKER_POT_COUNT; i++) {
if(POKER_POTS[i].players[player] == 0) break;
expectedGain += POKER_POTS[i].chips;
}
// Now work out the pot odds, this is basically "how many times the callbet
// could I win if I win this hand". e.g. Desirable hands will have an
// expected gain much higher than the callbet.
//TODO: not float
potOdds = callBet / (callBet + expectedGain);
} else {
// If the call bet is zero then there's fairly equal odds, so let's just
// take the chances out of the remainig player count.
potOdds = 1000 / pokerGetRemainingBetterCount();
}
// Now determine the expected ROI
// TODO: not float
expectedGain = confidence / potOdds;
// Now get a random number 0-100.
random = rand() % 100;
// Determine the max bet that the AI is willing to make. This is valued as
// "3/4 chips remaining - random(0-50)" and subtract the callbet. I will
// probably chance this since the random 0-50 is.. random
// TODO: Rewrite this
maxBet = plyr->chips - (random / 2);
maxBet -= callBet;
// Determine what's a good bluff bet.
// TODO: not float
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 < 800 && confidence < 800) {
if(random < 95) {
amount = 0;
} else {
amount = bluffBet;
isBluff = true;
}
} else if ((expectedGain < 1000 && confidence < 850) || confidence < 100) {
if (random < 80) {
amount = 0;
} else if(random < 5) {
amount = callBet;
isBluff = true;
} else {
amount = bluffBet;
isBluff = true;
}
} else if ((expectedGain < 1300 && confidence < 900) || confidence < 500) {
if (random < 60 || confidence < 500) {
amount = callBet;
} else {
amount = maxBet;
}
} else if (confidence < 950 || POKER_COMMUNITY_SIZE < 0x04) {
if(random < 20) {
amount = callBet;
} else {
amount = maxBet;
}
} else {
amount = (plyr->chips - callBet) * 9 / 10;
}
// If this is the first round... make it a lot less likely I'll bet
if(POKER_COMMUNITY_SIZE == 0x00 && amount > callBet) {
if(random > 5) amount = callBet;
}
// Did we actually bet?
if(amount > 0) {
// Let's not get caught in a raising loop with AI.
if(plyr->timesRaised >= POKER_TURN_MAX_RAISES) {
amount = callBet;
}
amount = MATH_MAX(amount, callBet);
// turn = pokerTurnBet(poker, playerIndex, amount);
turn->confidence = confidence;
} else if(pokerCanPlayerCheck(player)) {
// turn = pokerTurnBet(poker, playerIndex, 0);
turn->confidence = 1000;
} else {
// turn = pokerTurnFold(poker, playerIndex);
turn->confidence = 1000 - confidence;
}
}
inline bool pokerCanPlayerCheck(uint8_t player) {
return (
POKER_POTS[POKER_POT_CURRENT].players[player] ==
POKER_POTS[POKER_POT_CURRENT].call
);
}
inline bool pokerDoesPlayerNeedToBet(uint8_t playerIndex) {
uint8_t i;
pokerplayer_t *player = POKER_PLAYERS + playerIndex;
// Can this player even participate?
if(
(player->state & (POKER_PLAYER_STATE_FOLDED|POKER_PLAYER_STATE_OUT)) != 0 ||
player->chips == 0
) {
return false;
}
// Has the player bet? If so are they in the current pot?
if((player->state & POKER_PLAYER_STATE_HAS_BET_THIS_ROUND) == 0) {
return true;
}
//TODO: Refer to pokerbet function, but basically I can't let the player
//bet if they have bet more money than the second richest player.
// Check each pot, if the pot is inactive or the player is CALLED/CHECKED
for(i = 0; i < POKER_POT_COUNT_MAX; i++) {
// Is this pot active?
if(POKER_POTS[i].chips == 0) break;
// Is the player called into this pot all the way?
if(POKER_POTS[i].players[playerIndex] == POKER_POTS[i].call) continue;
return true;
}
return false;
}
inline uint8_t pokerGetRemainingBetterCount() {
uint8_t i, count;
count = 0;
for(i = 0 ; i < POKER_PLAYER_COUNT_MAX; i++) {
if(pokerDoesPlayerNeedToBet(i)) count++;
}
return count;
}