Source code for haive.games.hold_em.example

#!/usr/bin/env python3
"""Example usage of the Texas Hold'em poker implementation.

This example script demonstrates how to:
    - Create and configure a Texas Hold'em game
    - Set up player agents with different playing styles
    - Run a complete game with the Rich UI
    - Access and analyze game results

Run this script directly to see a Hold'em game in action.

"""

import argparse
import logging
import traceback

from haive.games.hold_em import HoldemGameAgent, HoldemGameAgentConfig
from haive.games.hold_em.aug_llms import get_complete_llm_suite
from haive.games.hold_em.config import (
    create_cash_game_config,
    create_default_holdem_config,
    create_heads_up_config,
    create_tournament_config,
)
from haive.games.hold_em.player_agent import HoldemPlayerAgentConfig
from haive.games.hold_em.state import HoldemState
from haive.games.hold_em.ui import HoldemRichUI

# Set up logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("holdem_example")


[docs] def create_custom_game( player_names: list[str], player_styles: list[str] | None = None, starting_chips: int = 1000, small_blind: int = 10, big_blind: int = 20, max_hands: int = 50, ) -> HoldemGameAgent: """Create a custom Hold'em game with specified players and settings. Args: player_names: List of player names player_styles: Optional list of player styles (defaults to "balanced" for all) starting_chips: Starting chips per player small_blind: Small blind amount big_blind: Big blind amount max_hands: Maximum hands to play Returns: HoldemGameAgent: Configured game agent ready to run """ if player_styles is None: player_styles = ["balanced"] * len(player_names) # Ensure player_styles is the same length as player_names if len(player_styles) != len(player_names): player_styles = player_styles[: len(player_names)] player_styles.extend(["balanced"] * (len(player_names) - len(player_styles))) logger.info(f"Creating custom game with {len(player_names)} players") logger.info(f"Player lineup: {', '.join(player_names)}") logger.info(f"Styles: {', '.join(player_styles)}") logger.info(f"Starting chips: {starting_chips}, Blinds: {small_blind}/{big_blind}") # Create player configurations player_configs = [] for i, (name, style) in enumerate(zip(player_names, player_styles, strict=False)): logger.info(f"Setting up {name} ({style} style)") # Create specialized LLMs for this player player_engines = get_complete_llm_suite(style) logger.info(f"Created {len(player_engines)} specialized engines for {name}") # Create player config player_config = HoldemPlayerAgentConfig( name=f"player_{name.lower()}", player_name=name, player_style=style, risk_tolerance=0.3 + (i * 0.1), # Vary risk tolerance engines=player_engines, state_schema=HoldemState, ) player_configs.append(player_config) logger.info(f"Added player: {name} ({style})") # Create main game configuration game_config = HoldemGameAgentConfig( name="custom_holdem_game", state_schema=HoldemState, max_players=len(player_names), small_blind=small_blind, big_blind=big_blind, starting_chips=starting_chips, max_hands=max_hands, player_configs=player_configs, ) # Create the game agent agent = HoldemGameAgent(game_config) logger.info("Game agent created successfully") return agent
[docs] def run_example_game(game_type: str = "default", delay: float = 1.5): """Run an example Hold'em game with the specified configuration. Args: game_type: Type of game to run ("default", "heads-up", "tournament", "cash", "custom") delay: Delay between UI updates (seconds) """ try: if game_type == "default": logger.info("Running default Hold'em game") config = create_default_holdem_config( num_players=4, starting_chips=1000, small_blind=10, big_blind=20 ) agent = HoldemGameAgent(config) elif game_type == "heads-up": logger.info("Running heads-up Hold'em game") config = create_heads_up_config( player1_name="Alice", player2_name="Bob", starting_chips=1000, big_blind=20, ) agent = HoldemGameAgent(config) elif game_type == "tournament": logger.info("Running tournament Hold'em game") config = create_tournament_config(num_players=6, starting_chips=1500) agent = HoldemGameAgent(config) elif game_type == "cash": logger.info("Running cash game Hold'em") config = create_cash_game_config( num_players=6, big_blind=20, max_buy_in=2000 ) agent = HoldemGameAgent(config) elif game_type == "custom": logger.info("Running custom Hold'em game") player_names = ["Alice", "Bob", "Charlie", "Diana"] player_styles = ["tight", "loose", "aggressive", "balanced"] agent = create_custom_game( player_names=player_names, player_styles=player_styles, starting_chips=1000, small_blind=10, big_blind=20, ) else: logger.error(f"Unknown game type: {game_type}") return # Run the game with the Rich UI ui = HoldemRichUI() logger.info("Starting game with Rich UI") ui.run(agent, delay=delay) logger.info("Game completed") except Exception as e: logger.error(f"Error running game: {e}") logger.error(traceback.format_exc())
[docs] def analyze_game_results(agent: HoldemGameAgent): """Analyze the results of a completed game. Args: agent: The game agent after running a game """ # Access the final state if not hasattr(agent, "app") or not hasattr(agent.app, "last_state"): logger.error("No game results available for analysis") return final_state = agent.app.last_state if not final_state: logger.error("No final state available") return # Print game summary logger.info("\n=== GAME SUMMARY ===") logger.info(f"Hands played: {final_state.hand_number - 1}") logger.info(f"Final pot: {final_state.total_pot}") # Player results logger.info("\n=== PLAYER RESULTS ===") for player in final_state.players: logger.info( f"{player.name}: {player.chips} chips, Status: {player.status.value}" ) # Hand history if final_state.hand_history: logger.info("\n=== HAND HISTORY ===") for _i, hand in enumerate(final_state.hand_history[-5:]): # Last 5 hands winner_name = "Unknown" for player in final_state.players: if player.player_id == hand.get("winner"): winner_name = player.name break logger.info( f"Hand #{hand.get('hand_number')}: {winner_name} won { hand.get('pot_size') } chips" )
[docs] def main(): """Main entry point with command line argument handling.""" parser = argparse.ArgumentParser( description="Texas Hold'em Example Runner", formatter_class=argparse.RawDescriptionHelpFormatter, epilog=""" Examples: python example.py # Run default game python example.py --type heads-up # Run heads-up game python example.py --type tournament # Run tournament python example.py --type custom # Run custom game """, ) parser.add_argument( "--type", "-t", default="default", choices=["default", "heads-up", "tournament", "cash", "custom"], help="Type of game to run", ) parser.add_argument( "--delay", "-d", type=float, default=1.5, help="Delay between UI updates (seconds)", ) parser.add_argument( "--analyze", "-a", action="store_true", help="Analyze game results after completion", ) args = parser.parse_args() # Run the specified game run_example_game(args.type, args.delay)
if __name__ == "__main__": # Run a quick heads-up game for testing print("Running quick Hold'em heads-up game example...") run_example_game("heads-up", delay=0.1) print("\nExample completed!")