Source code for haive.games.fox_and_geese.enhanced_example

#!/usr/bin/env python3
"""Enhanced example runner for Fox and Geese game with Rich UI visualization."""

import argparse
import time
import uuid

from rich.console import Console
from rich.panel import Panel

from haive.games.fox_and_geese.agent import FoxAndGeeseAgent
from haive.games.fox_and_geese.config import FoxAndGeeseConfig
from haive.games.fox_and_geese.models import FoxAndGeeseMove, FoxAndGeesePosition
from haive.games.fox_and_geese.rich_ui import FoxAndGeeseRichUI
from haive.games.fox_and_geese.state import FoxAndGeeseState
from haive.games.fox_and_geese.ui import FoxAndGeeseUI

# Set up logging - uncomment to see detailed debug logs
# logging.basicConfig(level=logging.DEBUG)


[docs] def run_fox_and_geese_game( agent: FoxAndGeeseAgent, delay: float = 1.5, use_rich_ui: bool = True ): """Run a Fox and Geese game with visualization. Args: agent: Configured FoxAndGeeseAgent delay: Delay between moves in seconds use_rich_ui: Whether to use the enhanced Rich UI (vs. the basic UI) Returns: The final game state """ console = Console() console.print( Panel( f"Starting Fox and Geese game with { 'Enhanced' if use_rich_ui else 'Basic' } Rich UI visualization", title="🦊 Fox and Geese Game 🪿", border_style="magenta", ) ) try: # Create the appropriate UI if use_rich_ui: ui = FoxAndGeeseRichUI(console=console) else: ui = FoxAndGeeseUI(console=console) # Display welcome message ui.display_welcome() time.sleep(delay) # Run the game with UI if use_rich_ui and hasattr(ui, "run_fox_and_geese_game"): # The enhanced UI has its own game running method final_state = ui.run_fox_and_geese_game(agent, delay=delay) else: # Use the agent's method for the basic UI if hasattr(agent, "ui"): agent.ui = ui final_state = agent.run_game_with_ui(delay=delay) # Print final message console.print("\n") console.print( Panel( "Game has completed! Thanks for playing!", title="🎮 Game Complete 🎮", border_style="green", ) ) return final_state except Exception as e: console.print(f"[bold red]Error running game: {e}[/bold red]") import traceback console.print( Panel( traceback.format_exc(), title="Error Details", border_style="red", ) ) return None
[docs] def demo_ui_features(delay: float = 0.5): """Demonstrate UI features with a sample game state. Args: delay: Delay between demonstrations in seconds """ console = Console() ui = FoxAndGeeseRichUI(console=console) # Create a sample game state game_state = FoxAndGeeseState.initialize() # Show the welcome message console.print( Panel( "UI Feature Demonstration", title="🦊 Fox and Geese UI Demo 🪿", border_style="magenta", ) ) time.sleep(delay) # Show the welcome screen ui.display_welcome() time.sleep(delay * 2) # Show the initial state console.print(Panel("Initial Game State", title="Demo", border_style="cyan")) ui.display_state(game_state) time.sleep(delay * 2) # Show thinking animation console.print(Panel("Thinking Animation", title="Demo", border_style="cyan")) ui.show_thinking("fox", "Considering my move...") time.sleep(delay) ui.show_thinking("geese", "Planning our strategy...") time.sleep(delay * 2) # Create some sample moves and positions to highlight fox_pos = FoxAndGeesePosition(row=3, col=3) move1 = FoxAndGeeseMove( from_pos=fox_pos, to_pos=FoxAndGeesePosition(row=2, col=2), piece_type="fox", capture=None, ) # Add a sample move to the history game_state.move_history.append(move1) # Update the fox position game_state.fox_position = move1.to_pos # Create sample legal moves legal_moves = [ FoxAndGeeseMove( from_pos=game_state.fox_position, to_pos=FoxAndGeesePosition(row=1, col=1), piece_type="fox", capture=None, ), FoxAndGeeseMove( from_pos=game_state.fox_position, to_pos=FoxAndGeesePosition(row=3, col=1), piece_type="fox", capture=None, ), FoxAndGeeseMove( from_pos=game_state.fox_position, to_pos=FoxAndGeesePosition(row=1, col=3), piece_type="fox", capture=None, ), ] # Show the state with highlighted positions console.print(Panel("Highlighted Positions", title="Demo", border_style="cyan")) highlight_positions = { FoxAndGeesePosition(row=1, col=1), FoxAndGeesePosition(row=3, col=1), } ui.display_state( game_state, highlight_positions=highlight_positions, legal_moves=legal_moves ) time.sleep(delay * 2) # Create a capture move capture_move = FoxAndGeeseMove( from_pos=game_state.fox_position, to_pos=FoxAndGeesePosition(row=0, col=0), piece_type="fox", capture=FoxAndGeesePosition(row=1, col=1), ) # Show capture animation console.print(Panel("Capture Animation", title="Demo", border_style="cyan")) ui.show_move(capture_move, game_state, game_state) time.sleep(delay * 2) # Update game state to simulate game progress game_state.fox_position = capture_move.to_pos game_state.move_history.append(capture_move) game_state.num_geese -= 1 # Remove a captured goose if capture_move.capture in game_state.geese_positions: game_state.geese_positions.remove(capture_move.capture) # Show game in progress console.print(Panel("Game in Progress", title="Demo", border_style="cyan")) ui.display_state(game_state) time.sleep(delay * 2) # Show final results game_state.game_status = "fox_win" game_state.winner = "fox" console.print(Panel("Final Results", title="Demo", border_style="cyan")) ui.display_final_results(game_state)
# Entry point if __name__ == "__main__": parser = argparse.ArgumentParser( description="Run the Fox and Geese game with Rich UI" ) parser.add_argument("--demo", action="store_true", help="Run a UI demonstration") parser.add_argument( "--basic-ui", action="store_true", help="Use the basic UI instead of enhanced UI", ) parser.add_argument( "--delay", type=float, default=1.2, help="Delay between moves in seconds" ) args = parser.parse_args() console = Console() try: if args.demo: # Run the UI demo demo_ui_features(delay=args.delay) else: # Create agent config config = FoxAndGeeseConfig( name="fox_and_geese_game", enable_analysis=True, visualize=True, runnable_config={ "configurable": { "thread_id": uuid.uuid4().hex[:8], "recursion_limit": 400, } }, ) # Create agent agent = FoxAndGeeseAgent(config) try: # Run the game in basic UI mode only for now run_fox_and_geese_game(agent, delay=args.delay, use_rich_ui=False) except Exception as e: console.print(f"[bold red]Error running game: {e}[/bold red]") traceback.print_exc() except Exception as e: console.print(f"[bold red]Critical error: {e}[/bold red]") import traceback console.print( Panel( traceback.format_exc(), title="Error Details", border_style="red", ) ) import traceback