Skip to content

Commit

Permalink
Add AI integrated into game
Browse files Browse the repository at this point in the history
  • Loading branch information
Gongsta committed Jun 17, 2024
1 parent c953e85 commit 08ecaa1
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 5 deletions.
5 changes: 3 additions & 2 deletions src/abstraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ def create_abstraction_folders():
os.makedirs(f"../data/{split}/{stage}")


def calculate_equity(player_cards: List[str], community_cards=[], n=1000, timer=False):
def calculate_equity(player_cards: List[str], community_cards=[], n=2000, timer=False):
if timer:
start_time = time.time()
wins = 0
Expand All @@ -254,7 +254,8 @@ def calculate_equity(player_cards: List[str], community_cards=[], n=1000, timer=
if player_score < opponent_score:
wins += 1
elif player_score == opponent_score:
wins += 0.5
wins += 1
# wins += 0.5

if timer:
print("Time it takes to call function: {}s".format(time.time() - start_time))
Expand Down
122 changes: 122 additions & 0 deletions src/aiplayer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import joblib
import pyttsx3
import numpy as np
from player import Player
from abstraction import calculate_equity


def getAction(strategy):
return np.random.choice(list(strategy.keys()), p=list(strategy.values()))


class AIPlayer(Player):
def __init__(self, balance) -> None:
super().__init__(balance)
self.is_AI = True

self.engine = pyttsx3.init()

# We are going to have the dumbest AI possible, which is to call every time
def place_bet(self, observed_env) -> int: # AI will call every time
# strategy = observed_env.get_average_strategy()
if "k" in observed_env.valid_actions():
action = "k"
else:
action = "c"

card_str = [str(card) for card in self.hand]
community_cards = [str(card) for card in observed_env.community_cards]
# if observed_env.game_stage == 2:
equity = calculate_equity(card_str, community_cards)

# fold, check / call, raise
np_strategy = np.abs(np.array([1.0 - (equity + equity / 2.0), equity, equity / 2.0]))
np_strategy = np_strategy / np.sum(np_strategy) # normalize

if observed_env.stage_pot_balance == 0: # no bet placed
if self == observed_env.get_player(
observed_env.dealer_button_position
): # If you are the dealer, raise more of the time
strategy = {
"k": np_strategy[0],
f"b{min(observed_env.BIG_BLIND, self.player_balance)}": np_strategy[2],
f"b{min(observed_env.total_pot_balance, self.player_balance)}": np_strategy[1],
}
else:
strategy = {
"k": equity,
f"b{min(observed_env.total_pot_balance, self.player_balance)}": 1 - equity,
}

else: # if there is a bet already
# TODO: calculate proportional to bet size
# normalize the strategy
if "k" in observed_env.valid_actions():
strategy = {
"k": np_strategy[0],
f"b{min(int(1.5 * observed_env.get_highest_current_bet()), self.player_balance)}": np_strategy[
1
],
f"b{min(2 * observed_env.get_highest_current_bet(), self.player_balance)}": np_strategy[
2
],
}
else:
strategy = {
"f": np_strategy[0],
"c": np_strategy[1],
f"b{min(2 * observed_env.get_highest_current_bet(), self.player_balance)}": np_strategy[
2
],
}

print(card_str, community_cards)
print(observed_env.get_highest_current_bet())
print("equity", equity)
print("AI strategy ", strategy)
action = getAction(strategy)

# history = HoldEmHistory(observed_env.history)
# strategy = observed_env.get_average_strategy()

# print("AI strategy", strategy)
# print("AI action", action)

if action == "k": # check
if observed_env.game_stage == 2:
self.current_bet = 2
else:
self.current_bet = 0

self.engine.say("I Check")
elif action == "c":
self.engine.say("I Call")
# If you call on the preflop
self.current_bet = observed_env.get_highest_current_bet()
elif action == "f":
self.engine.say("I Fold")
else:
self.current_bet = int(action[1:])
if self.current_bet == self.player_balance:
self.engine.say("I'm All-In! What are you gonna do young man?")
self.engine.say(f"I bet {self.current_bet}")

self.engine.runAndWait()
return action


def load_holdem_infosets():
print("loading holdem infosets")
global holdem_infosets
# holdem_infosets = joblib.load("../src/infoSets_100.joblib")
holdem_infosets = joblib.load("../src/infoSets_0.joblib")
print("loaded holdem infosets!")


def get_infoset(infoSet_key):
print("getting infoset", infoSet_key)
key = "".join(infoSet_key)
if key in holdem_infosets:
return holdem_infosets[key]
else:
return None
7 changes: 5 additions & 2 deletions src/environment.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# The Poker Environment
from evaluator import *
from typing import List
from player import Player, AIPlayer
from player import Player
from aiplayer import AIPlayer


class PokerEnvironment:
"""
Expand Down Expand Up @@ -40,7 +42,7 @@ def __init__(self) -> None:
self.SMALL_BLIND = 1
self.BIG_BLIND = 2

self.INPUT_CARDS = False
self.INPUT_CARDS = True

self.history = []
self.players_balance_history = [] # List of "n" list for "n" players
Expand Down Expand Up @@ -117,6 +119,7 @@ def count_remaining_players_in_round(self):
def start_new_round(self):
assert len(self.players) >= 2 # We cannot start a poker round with less than 2 players...

self.new_player_balance = int(input("Enter the starting balance for the players: "))
# Reset Players
for player in self.players:
player.playing_current_round = True
Expand Down
1 change: 0 additions & 1 deletion src/evaluator.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,6 @@ def get_winner(
hand_strengths = [hand.hand_strength for hand in self.hands]
best_hand_val = min(hand_strengths)
potential_winners = [i for i, x in enumerate(hand_strengths) if x == best_hand_val]
print(potential_winners)

# TODO: Idea to optimize in the future, just make the best hand as a list, and then compare if necessary.

Expand Down

0 comments on commit 08ecaa1

Please sign in to comment.