chironaut 0.3.5

A poker game library for Texas Hold'em and other poker variants
Documentation
use chironaut::{
    action::Action,
    game::Game,
    rules::GameRules,
};

fn main() {
    println!("=== SMALL BLIND CALLING TEST ===\n");
    
    // Create a No-Limit Hold'em game with 1/2 blinds
    let rules = GameRules::nlhe(1, 2);
    let mut game = Game::new(rules);

    // Add three players with 1000 chips each
    println!("Setting up 3 players with 1000 chips each");
    game.add_player_to_seat("Player 1 (BB)".to_string(), 1000, 0).unwrap();
    game.add_player_to_seat("Player 2 (BTN)".to_string(), 1000, 1).unwrap();
    game.add_player_to_seat("Player 3 (SB)".to_string(), 1000, 2).unwrap();
    
    // Start a hand
    match game.start_hand() {
        Ok(_) => {
            println!("Hand started successfully");
            
            // Show blinds and initial state
            println!("\nInitial state after blinds:");
            print_player_status(&game);
            println!("Pot: {}", game.pot);
            println!("Current bet: {}", game.current_bet);
            println!("Stage: {:?}", game.stage);
            
            // First to act is the dealer (Player 2)
            println!("\nCurrent position: {} ({})", 
                game.current_position, 
                game.players[game.current_position].name);
            
            // Dealer calls
            println!("\nPREFLOP: Dealer calls with 2 chips:");
            match game.handle_action(Action::Bet(2)) {
                Ok(_) => println!("  Call successful"),
                Err(e) => println!("  ERROR: Call was rejected: {}", e),
            }
            
            // Now action should be on the small blind (Player 3)
            println!("\nCurrent position: {} ({})", 
                game.current_position, 
                game.players[game.current_position].name);
            
            // Small blind calls by adding 1 more chip
            println!("\nPREFLOP: Small blind calls by adding 1 more chip:");
            match game.handle_action(Action::Bet(1)) {
                Ok(_) => println!("  Call successful - correctly accepted amount less than big blind"),
                Err(e) => println!("  ERROR: Call was rejected: {}", e),
            }
            
            // Show state after the call
            println!("\nState after small blind call:");
            print_player_status(&game);
            println!("Pot: {}", game.pot);
            println!("Current bet: {}", game.current_bet);
            
            // Explain the results
            println!("\n=== RESULTS EXPLANATION ===");
            println!("Small blind already posted 1 chip");
            println!("Small blind only needs to add 1 more chip to call the big blind of 2");
            println!("This action should be allowed even though the bet amount (1) is less than the big blind (2)");
            println!("The game correctly handles small blind calls preflop.");
        },
        Err(e) => {
            println!("Error starting hand: {}", e);
        }
    }
}

fn print_player_status(game: &Game) {
    for (i, player) in game.players.iter().enumerate() {
        println!("Player {} ({})", i, player.name);
        
        // Determine position label
        let position_label = if player.is_dealer {
            "Dealer (BTN)"
        } else if i == game.get_small_blind_position() {
            "Small Blind"
        } else {
            "Big Blind"
        };
        
        println!("  Position: {}", position_label);
        println!("  Chips: {}", player.chips);
        println!("  Bet amount: {}", player.bet_amount);
        println!("  Folded: {}", player.is_folded);
        println!("  All-in: {}", player.is_all_in);
    }
}