chironaut 0.3.5

A poker game library for Texas Hold'em and other poker variants
Documentation
use crate::card::Card;
use crate::hand::Hand;
use crate::action::Action;

#[derive(Debug, Clone)]
pub struct Player {
    pub id: usize,
    pub name: String,
    pub chips: u32,
    pub seat_position: usize, // Physical seat at the table
    pub hand: Hand,
    pub bet_amount: u32,
    pub is_folded: bool,
    pub is_all_in: bool,
    pub is_dealer: bool,
}

impl Player {
    pub fn new(id: usize, name: String, chips: u32, seat: usize) -> Self {
        Self {
            id,
            name,
            chips,
            seat_position: seat,
            hand: Hand::new(),
            bet_amount: 0,
            is_folded: false,
            is_all_in: false,
            is_dealer: false,
        }
    }
    
    pub fn receive_card(&mut self, card: Card) {
        self.hand.add_card(card);
    }
    
    /// Bet a certain amount of chips
    pub fn bet(&mut self, amount: u32) -> u32 {
        // Limit the bet to player's available chips
        let actual_amount = amount.min(self.chips);
        
        // Update chip counts
        self.chips -= actual_amount;
        self.bet_amount += actual_amount;
        
        // Check if player is now all-in
        if self.chips == 0 {
            self.is_all_in = true;
        }
        
        actual_amount
    }
    
    pub fn fold(&mut self) {
        self.is_folded = true;
    }
    
    pub fn collect_winnings(&mut self, amount: u32) {
        self.chips += amount;
    }
    
    pub fn reset_for_new_hand(&mut self) {
        self.hand.clear();
        self.bet_amount = 0;
        self.is_folded = false;
        self.is_all_in = false;
    }
    
    /// Check if the player can perform the given action
    pub fn can_perform_action(&self, action: &Action, current_bet: u32) -> bool {
        // If player has folded or is all-in, they can't take any action
        if self.is_folded || self.is_all_in {
            return false;
        }
        
        match action {
            Action::Fold => true, // Player can always fold
            Action::Bet(amount) => {
                if *amount == 0 {
                    // Check is only valid if no bet to call
                    return self.bet_amount == current_bet;
                }
                
                // If player is betting all their chips, it's a valid all-in
                if *amount == self.chips {
                    return true;
                }
                
                // Otherwise, ensure player has enough chips
                if *amount > self.chips {
                    return false;
                }
                
                // If betting less than the amount needed to call, it's not valid
                // (unless it's an all-in, which we already checked)
                if self.bet_amount + *amount < current_bet {
                    return false;
                }
                
                true
            },
            Action::Post(amount) => *amount <= self.chips, // Can only post if have enough chips
        }
    }
}