A Texas Hold'em poker bot competition framework for heads-up matches. This system allows you to create, test, and compete poker bots against each other.
This framework provides:
- A poker game engine that handles all the rules of Texas Hold'em
- A hand evaluation system to determine winning hands
- Example bot strategies to demonstrate the API
- A tournament manager to run matches and competitions
- A visual interface using Pygame to display poker matches
- Predefined poker rounds for testing and debugging
- Python 3.6 or higher
- Pygame (for visualization features)
- tqdm (for progress bars)
Install the required packages:
pip install pygame tqdmTo run a demonstration of the poker game with visual interface:
python game.pyThis will run a visual demonstration match between the example bots, one of which is a bot you can control manually.
The core game engine that implements Texas Hold'em rules:
- Manages game state
- Deals cards
- Processes player actions
- Handles betting rounds
- Determines winners
Provides functionality to evaluate poker hands:
- Identifies hand types (pair, flush, etc.)
- Evaluates the best 5-card hand from 7 cards
- Compares hands to determine the winner
- Calculates preflop hand strength
- Provides percentile rankings for preflop hands
- Calculates head-to-head equity
Several example bot strategies are provided:
- Conservative Bot (
strategy/example_strategy_1.py): A cautious bot that plays based on hand strength and folds weaker hands - Aggressive Bot (
strategy/example_strategy_2.py): A more aggressive bot that bluffs frequently and plays more hands - Simple Bot (
strategy/example_strategy_0.py): A basic bot for demonstration purposes - Human Player (
strategy/human_strategy.py): Allows human players to compete against bots
Manages matches and tournaments:
- Runs individual matches
- Conducts round-robin tournaments
- Tracks and reports results
- Can run visual matches with Pygame
- Supports alternating starting positions
A Pygame-based visualization system that:
- Displays cards, chips, and the poker table
- Shows player actions and betting in real-time
- Dramatizes important moments like showdowns
- Displays hand strength and percentile rankings
- Provides a UI for tournament finals
The framework includes predefined poker round configurations for:
- Testing specific scenarios
- Ensuring consistent testing across different bot implementations
- Debugging bot behavior in specific situations
To create your own poker bot:
- Create a new Python class with a
get_actionmethod that takes a game state dictionary and returns an action - The bot must implement the following methods:
__init__(self, name): Constructor that accepts a name parameter__str__(self): Return the bot's nameget_action(self, game_state): Return the bot's action based on the current game state
A bot template is provided in strategy/bot_template.py to help you get started.
Your bot must implement the get_action method with this signature:
def get_action(self, game_state):
"""
Args:
game_state (dict): The current state of the game from the player's perspective
Returns:
dict: Action to take
"""
# Your strategy logic here
# Must return a dictionary with an 'action' key and possibly an 'amount' keyThe game state provided to your bot includes:
player_idx: Your position (0 or 1)hand: Your hole cards (e.g., ['Ah', 'Kd'])community_cards: Shared cards on the boardpot: Total pot sizecurrent_bet: Current bet to callmy_stack: Your remaining chipsopponent_stack: Opponent's remaining chipsmy_bet: Amount you've already bet in this roundopponent_bet: Amount opponent has bet in this roundmin_raise: Minimum raise amountante: Ante amount
Your bot must return one of these actions:
{'action': 'fold'}: Give up your hand{'action': 'check'}: Pass the action (only when there's no bet to call){'action': 'call'}: Match the current bet{'action': 'bet', 'amount': X}: Place a bet of amount X (when there's no existing bet){'action': 'raise', 'amount': X}: Raise to a total of X (when there's an existing bet)
class MyPokerBot:
def __init__(self, name="MyPokerBot"):
self.name = name
def __str__(self):
return self.name
def get_action(self, game_state):
# Extract information from game state
hand = game_state['hand']
community_cards = game_state['community_cards']
pot = game_state['pot']
current_bet = game_state['current_bet']
my_stack = game_state['my_stack']
# Implement your strategy here
# This is a very simple example that just calls any bet
if current_bet == 0:
return {'action': 'check'}
else:
return {'action': 'call'}You can test your bot in several ways:
- Standard Tournament: Run a tournament against the provided example bots
- Custom Scenarios: Test against specific poker rounds in the
poker_rounds/directory - Visual Match: Watch your bot play in the visual interface
- Play Against Your Bot: Use the human player interface to play against your bot
The poker_rounds/ directory contains JSON files with specific card configurations that can be used for testing and debugging:
# Example of using a predefined round for testing
from src.poker_engine import PokerEngine
from src.utils import load_cards_from_json
# Load predefined cards
round_cards = load_cards_from_json("poker_rounds/round_1_cards.json")
# Initialize engine with predefined cards
engine = PokerEngine(
player1_bot=my_bot,
player2_bot=opponent_bot,
predefined_cards=round_cards
)
# Run the game
result = engine.play_hand()To run a tournament with your own bots:
from src.poker_tournament import PokerTournament
from my_bot import MyPokerBot
from strategy.example_strategy_1 import ConservativeBot
# Create bot instances
my_bot = MyPokerBot("MyAwesomeBot")
opponent = ConservativeBot("ConservativeBot")
# Create tournament manager
tournament = PokerTournament(starting_stack=1000, ante=10)
# Run a match
tournament.run_match(my_bot, opponent, num_hands=100)
# Run a tournament with multiple bots
bots = [my_bot, opponent, AnotherBot("AnotherBot")]
tournament.run_tournament(bots, num_matches=5, hands_per_match=50)
# Run a tournament with visualized finals
tournament.run_tournament(bots, num_matches=5, hands_per_match=50, visualize_finals=True)For a more engaging experience, you can run matches with visual display:
from src.poker_visualizer import run_visual_match
from src.poker_tournament import run_visual_tournament
from my_bot import MyPokerBot
from strategy.example_strategy_1 import ConservativeBot
# Create bot instances
my_bot = MyPokerBot("MyAwesomeBot")
opponent = ConservativeBot("ConservativeBot")
# Run a single visual match
run_visual_match(my_bot, opponent, hands=5, delay=0.5)
# Run a tournament with visualization for the finals
run_visual_tournament([my_bot, opponent], matches_per_pair=2, hands_per_match=10, delay=0.5)You can also play against a bot yourself:
python -m src.play_against_botThis launches an interactive interface where you can play Texas Hold'em against any of the implemented bots.
When running a visualization:
- Press any key to advance through the stages of the match
- Press ESC to quit
- Watch as cards are dealt, bets are made, and hands are evaluated
- Hand percentiles and rankings are displayed to help understand the quality of hands
The hand_evaluator.py module provides useful functions for evaluating poker hands:
from hand_evaluator import calculate_preflop_strength, preflop_percentile, preflop_rank_description, calculate_head_to_head_equity
# Get the preflop strength of a hand (0.0 - 1.0)
strength = calculate_preflop_strength(['Ah', 'Kh'], style='balanced')
# Get the percentile of a preflop hand (0.0 - 1.0)
percentile = preflop_percentile(['Ah', 'Kh'])
# Calculate equity between two hands
equity = calculate_head_to_head_equity(['Ah', 'Kh'], ['Qd', 'Jd'])Contributions to the ACM Poker Bot Competition framework are welcome! Feel free to submit pull requests with bug fixes, improvements, or new bot strategies.