1 unstable release
new 0.1.0 | Apr 27, 2025 |
---|
#96 in Games
74KB
1.5K
SLoC
Deadman
A Rust poker library for simulating Texas Hold'em and Omaha poker variants.
Overview
Deadman is a comprehensive poker game library designed to create, simulate, and analyze poker games. It supports multiple poker variants including:
- No-Limit Texas Hold'em
- Pot-Limit Omaha (4-card)
- Pot-Limit Omaha (5-card)
- Pot-Limit Omaha (6-card)
Features
- Create and manage poker games with customizable rules
- Add and remove players with specific seat positions
- Deal cards and handle betting rounds
- Process player actions (bet, call, raise, fold, check)
- Support for side pots and all-in situations
- Evaluate hands and determine winners
- Run the board multiple times after all-ins
- Game state snapshots for persistence/database storage
- JSON serialization support
Installation
Add this to your Cargo.toml
:
[dependencies]
deadman = { path = "path/to/deadman" }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" # For JSON serialization
Usage Examples
Basic Texas Hold'em Game
use deadman::{
action::Action,
game::Game,
rules::GameRules,
};
fn main() {
// Create a No-Limit Hold'em game with 10/20 blinds
let rules = GameRules::nlhe(10, 20);
let mut game = Game::new(rules);
// Add players
game.add_player_to_seat("Alice".to_string(), 1000, 0).unwrap();
game.add_player_to_seat("Bob".to_string(), 1000, 1).unwrap();
// Start a hand
game.start_hand().unwrap();
// Preflop action
game.handle_action(Action::Call).unwrap(); // Bob calls
game.handle_action(Action::Check).unwrap(); // Alice checks
// Deal flop
game.next_street().unwrap();
println!("Flop: {:?}", game.community_cards);
// Flop action
game.handle_action(Action::Check).unwrap(); // Alice checks
game.handle_action(Action::Bet(50)).unwrap(); // Bob bets
game.handle_action(Action::Call).unwrap(); // Alice calls
// Deal turn
game.next_street().unwrap();
println!("Turn: {:?}", game.community_cards);
// Continue with the game...
}
Running the Board Multiple Times
// After players are all-in
match game.run_multiple_times(3) {
Ok(result) => {
// Display results for each run
for (i, run) in result.runs.iter().enumerate() {
println!("Run #{}: {:?}", i+1, run.community_cards);
println!("Winners: {:?}", run.winning_player_indices);
}
// Distribute pot based on win percentages
game.complete_with_multiple_runs(3).unwrap();
},
Err(e) => println!("Error: {}", e),
}
Side Pots and All-In Situations
The library handles uneven stack sizes and creates appropriate side pots when players go all-in:
// Create a game with varying stack sizes
let rules = GameRules::nlhe(10, 20);
let mut game = Game::new(rules);
game.add_player_to_seat("Alice".to_string(), 1000, 0).unwrap();
game.add_player_to_seat("Bob".to_string(), 500, 1).unwrap();
game.add_player_to_seat("Charlie".to_string(), 200, 2).unwrap();
game.start_hand().unwrap();
// Preflop action
game.handle_action(Action::Call).unwrap(); // Charlie calls
game.handle_action(Action::Raise(200)).unwrap(); // Alice raises
// Bob goes all-in with his 500 chips
game.handle_action(Action::Raise(500)).unwrap();
// Charlie goes all-in with his smaller stack (200 chips)
game.handle_action(Action::Call).unwrap();
// Alice calls
game.handle_action(Action::Call).unwrap();
// Side pots will be automatically calculated
// - Main pot: 600 (200 × 3 players)
// - Side pot 1: 600 (300 × 2 players, Alice and Bob)
// When the hand completes, pots are awarded to appropriate winners
game.next_street().unwrap(); // Flop
game.next_street().unwrap(); // Turn
game.next_street().unwrap(); // River
game.next_street().unwrap(); // Showdown - side pots distributed automatically
The library handles:
- Players with different stack sizes
- Calculating correct side pots when players are all-in
- Evaluating each pot separately and awarding to appropriate winners
- Special handling for heads-up play
- Running the board multiple times with side pot distribution
Game State Snapshots
The library provides a robust snapshot system for saving and restoring game state. This is useful for:
- Persisting games in a database
- Creating game history and replays
- Supporting game recovery after crashes
- Analytics and post-game analysis
use deadman::{
game::{Game, GameSnapshot},
// other imports...
};
use serde_json;
// Take a snapshot of the current game state
let snapshot = game.get_snapshot();
// Serialize to JSON for database storage
let json = serde_json::to_string_pretty(&snapshot).unwrap();
// Save json to database...
// Later, restore the game from the snapshot
let loaded_snapshot: GameSnapshot = serde_json::from_str(&json).unwrap();
let restored_game = Game::from_snapshot(loaded_snapshot);
// Continue the game from where it was saved
restored_game.handle_action(Action::Check).unwrap();
// ...
The snapshot includes comprehensive state information:
- Game rules and current stage
- Player information (chips, hands, bet amounts)
- Community cards and pot size
- Dealer position and active player
- Deck state (for accurate game restoration)
- Side pot information
Library Structure
Game
: Main class for poker game managementPlayer
: Represents a player in the gameCard
: Represents a playing cardDeck
: Manages the deck of cardsAction
: Available player actions (call, bet, fold, etc.)GameRules
: Configure game variants and limitsGameStage
: Game stages (preflop, flop, turn, river, showdown)GameSnapshot
: For saving/loading game state
Game Variants
Create different game variants using these constructors:
// No-Limit Hold'em
let nlhe = GameRules::nlhe(small_blind, big_blind);
// Pot-Limit Omaha (4-card)
let plo4 = GameRules::plo4(small_blind, big_blind);
// 5-card PLO
let plo5 = GameRules::plo5(small_blind, big_blind);
// 6-card PLO
let plo6 = GameRules::plo6(small_blind, big_blind);
Examples
The library includes several examples:
basic_game.rs
: Simple Texas Hold'em game examplerun_it_multiple_times.rs
: Demonstrates running the board multiple timesgame_snapshot.rs
: Shows how to save and restore game stateomaha_variants.rs
: Examples of different Omaha variantsseat_selection.rs
: Player seat selection and management
Run examples with:
cargo run --example game_snapshot
License
MIT License
Copyright (c) 2023
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Dependencies
~0.9–1.8MB
~38K SLoC