Chironaut
A complete and flexible Texas Hold'em and Omaha poker engine written in Rust.
Features
- ๐ Support for Texas Hold'em and multiple Omaha variants (4, 5, and 6-card)
- ๐ฐ Fully functional betting logic with blinds, antes, raises, and all-in situations
- ๐ Side pot calculation and distribution with multiple all-in players
- ๐ฎ Simple action model for easy integration with user interfaces
- ๐คฒ Hand evaluation for all poker hand rankings
- ๐ Support for running it multiple times (2 or 3 runs)
- ๐พ Game state serialization for saving and loading games
- ๐งช Thoroughly tested with comprehensive test suite
Usage
Basic Game Setup
use ;
// Create a No-Limit Hold'em game with 10/20 blinds
let rules = nlhe;
let mut game = new;
// Add players
game.add_player.unwrap;
game.add_player.unwrap;
game.add_player.unwrap;
// Start a hand
game.start_hand.unwrap;
// Player actions are handled with the simplified Action model
// Player 1 calls the big blind
game.handle_action.unwrap;
// Player 2 raises to 60
game.handle_action.unwrap;
// Player 3 folds
game.handle_action.unwrap;
// Player 1 calls the raise
game.handle_action.unwrap;
// Move to the flop
game.next_street.unwrap;
println!;
Action Model
Chironaut uses a simplified action model to represent player actions:
Action::Fold- Player folds their hand and gives up claim to the potAction::Bet(amount)- A unified betting action that covers:- Check:
Bet(0)when current_bet = player's current bet - Call:
Bet(amount)to match the current bet - Raise:
Bet(amount)higher than the amount needed to call - All-in:
Bet(player.chips)to go all-in with remaining chips
- Check:
This unified model simplifies integration with user interfaces while maintaining all poker functionality.
All-in and Side Pots
The engine automatically handles all-in scenarios and side pot calculations:
// Player goes all-in with their remaining chips
let all_in_amount = game.players.chips;
game.handle_action.unwrap;
// When a round is complete with all-in players, side pots are calculated
if game.is_round_complete
// At showdown, pots are awarded to winners automatically
if game.stage == Showdown
Running Multiple Times
The engine supports running the community cards multiple times:
// After players are all-in, you can run the board multiple times
let run_count = 2; // Can be 2 or 3
let multi_run = game.run_multiple_times.unwrap;
// Pot is distributed proportionally based on run wins
game.complete_with_multiple_runs.unwrap;
Game State Serialization
Save and load game states:
// Save the current game state
let snapshot = game.get_snapshot;
let json = to_string.unwrap;
// Load a game from a saved state
let loaded_snapshot: GameSnapshot = from_json.unwrap;
let game = from_snapshot;
Seating and Blind Structure
In heads-up (2 player) games, the button posts the small blind and acts first preflop. After the flop, the big blind acts first.
For 3+ player games, the standard poker seating and blind structure applies:
- Button (dealer) is last to act
- Small blind is to the left of the button
- Big blind is to the left of the small blind
- First to act (UTG) is to the left of the big blind
Seat positions can be explicitly assigned:
// Add players to specific seats (0-based index)
game.add_player_to_seat.unwrap;
game.add_player_to_seat.unwrap;
game.add_player_to_seat.unwrap;
Testing
The library includes comprehensive tests for all functionality:
cargo test
Example CLI Application
A simple command-line poker game is included as an example:
use ;
License
MIT