chironaut 0.3.5

A poker game library for Texas Hold'em and other poker variants
Documentation
use std::fmt;

#[derive(Debug, Clone, PartialEq)]
pub enum Action {
    /// Fold: Player gives up their hand and any right to win the pot
    Fold,
    
    /// Bet: A unified betting action representing any amount commitment
    /// - bet(0) when current_bet = player.bet_amount -> Check
    /// - bet(current_bet - player.bet_amount) -> Call
    /// - bet(x) where x > current_bet - player.bet_amount -> Raise
    /// - bet(player.chips) -> All-in
    Bet(u32),
    
    /// Post: Used internally for blinds/antes (not player-initiated)
    Post(u32),
}

impl Action {
    pub fn amount(&self) -> u32 {
        match self {
            Action::Fold => 0,
            Action::Bet(amount) => *amount,
            Action::Post(amount) => *amount,
        }
    }
    
    /// Utility to check if the action is a check (bet of 0)
    pub fn is_check(&self, current_bet: u32, player_bet: u32) -> bool {
        if let Action::Bet(amount) = self {
            return *amount == 0 && current_bet == player_bet;
        }
        false
    }
    
    /// Utility to check if the action is a call (bet matches the current bet)
    pub fn is_call(&self, current_bet: u32, player_bet: u32) -> bool {
        if let Action::Bet(amount) = self {
            return player_bet + *amount == current_bet;
        }
        false
    }
    
    /// Utility to check if the action is a raise (bet exceeds the current bet)
    pub fn is_raise(&self, current_bet: u32, player_bet: u32) -> bool {
        if let Action::Bet(amount) = self {
            return player_bet + *amount > current_bet;
        }
        false
    }
    
    /// Utility to check if this is an all-in action
    pub fn is_all_in(&self, player_chips: u32) -> bool {
        if let Action::Bet(amount) = self {
            return *amount == player_chips;
        }
        false
    }
    
    /// Is this action aggressive (more than just matching the current bet)
    pub fn is_aggressive(&self, current_bet: u32, player_bet: u32) -> bool {
        if let Action::Bet(amount) = self {
            return player_bet + *amount > current_bet;
        }
        false
    }
    
    /// Is this action passive (checking or just calling)
    pub fn is_passive(&self, current_bet: u32, player_bet: u32) -> bool {
        if let Action::Bet(amount) = self {
            return *amount == 0 || player_bet + *amount == current_bet;
        }
        false
    }
    
    /// Is this a folding action
    pub fn is_folding(&self) -> bool {
        matches!(self, Action::Fold)
    }
}

impl fmt::Display for Action {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Action::Fold => write!(f, "fold"),
            Action::Bet(amount) => {
                // We don't have context about current_bet here, so just display as a bet
                write!(f, "bet {}", amount)
            },
            Action::Post(amount) => write!(f, "post {}", amount),
        }
    }
}