rusty_marvin/README.md
Jan-Peter v. Hunnius 14c56485e7 docs: clean up documentation - remove obsolete architecture docs, simplify roadmap and vision, update READMEs
- Delete ARCHITECTURE_HAND_LOGGING_TOURNAMENT_IMPROVEMENTS.md (implemented)
- Delete ARCHITECTURE_SUPERSONIC_EVALUATOR.md (implemented)
- Delete REFERENCES.md (no longer needed)
- Simplify ROADMAP.md: remove Phases 4-7 (live server, advanced bots)
- Simplify VISION.md: focus on simulation testbed only
- Update README.md: dual evaluator architecture, fix broken links
- Update holdem_core/README.md: fix title, add Supersonic evaluator docs
2026-05-25 12:19:44 +02:00

392 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Poker Simulation Testbed
[![Crates.io](https://img.shields.io/crates/v/holdem_core.svg)](https://crates.io/crates/holdem_core)
[![Documentation](https://docs.rs/holdem_core/badge.svg)](https://docs.rs/holdem_core)
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
A comprehensive poker simulation testbed and unit test framework for bot development. Features two Rust-native hand evaluators — the **Cactus Kev** perfect-hash evaluator (~100 KB tables) and the **Supersonic** LUT trie evaluator (~124 MB tables) — designed for automated poker bot testing, strategy analysis, and simulation at scale.
## Recent Updates
- **Supersonic Evaluator**: New high-throughput LUT trie evaluator (~124 MB) for O(n) hand evaluation
- **Dual Evaluator Architecture**: Choose between Cactus Kev (compact) and Supersonic (fast) per use case
- **Simulation Testbed**: Run cash games, SNGs, and MTTs with configurable bots via TOML
- **Input Validation**: Added comprehensive validation to `Card::new()` ensuring rank (0-12) and suit (0-3) are within valid ranges
- **Enhanced Documentation**: All public methods now include working code examples and panic condition documentation
- **Error Handling**: Improved error handling throughout the codebase with proper `Result` types
## Features
- **Bot Testing Framework**: Specifically designed for automated poker bot testing and development
- **Dual Evaluators**: Cactus Kev (compact ~100 KB) and Supersonic LUT trie (~124 MB) hand evaluators
- **Blazing Fast**: Sub-microsecond hand evaluation using perfect hash and trie-based lookup
- **Memory Efficient**: Choose between compact Cactus Kev tables or high-throughput Supersonic trie
- **Standards Compliant**: Based on proven poker evaluation algorithms
- **Multi-Hand Support**: Evaluate 5, 6, or 7-card poker hands
- **Texas Hold'em Ready**: Optimized for Texas Hold'em bot analysis and testing
- **Comprehensive Testing**: Extensive test suite with millions of verification cases
- **Deterministic Results**: Consistent hand evaluation for reproducible bot testing
- **Simulation Engine**: Run cash games, SNGs, and MTTs with configurable bots via TOML
## Performance
### Cactus Kev Evaluator
| Hand Type | Evaluation Time | Method |
|-----------|----------------|--------|
| 5-Card | ~50-100ns | Single prime-product hash → table lookup |
| 6-Card | ~300-500ns | Six 5-card lookups |
| 7-Card | ~1-2µs | 21 enumeration + HashMap cache |
### Supersonic Evaluator
| Hand Type | Evaluation Time | Method |
|-----------|----------------|--------|
| 5-Card | O(5) array lookups | Direct trie traversal |
| 6-Card | O(6) array lookups | Direct trie traversal |
| 7-Card | O(7) array lookups | Direct trie traversal |
## Documentation
For detailed project information, see:
- **[VISION.md](docs/VISION.md)** - Project goals and architectural vision
- **[ROADMAP.md](docs/ROADMAP.md)** - Future development phases and implementation plan
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
holdem_core = "0.1.0"
```
## Quick Start - Bot Testing
```rust
use holdem_core::{Card, Hand, HoleCards, Board, Evaluator};
use std::str::FromStr;
// Create cards from string notation
let ace_spades = Card::from_str("As").unwrap();
let king_spades = Card::from_str("Ks").unwrap();
// Create hole cards from notation
let hole_cards = HoleCards::from_notation("AKs").unwrap();
// Create a board with community cards
let board = Board::new()
.with_flop([
Card::from_str("Qh").unwrap(),
Card::from_str("Jh").unwrap(),
Card::from_str("Th").unwrap(),
]).unwrap()
.with_turn(Card::from_str("2c").unwrap()).unwrap()
.with_river(Card::from_str("3d").unwrap()).unwrap();
// Create a hand from hole cards and board
let hand = Hand::from_hole_cards_and_board(&hole_cards, &board).unwrap();
// Evaluate the hand
let evaluator = Evaluator::new().unwrap();
let hand_value = evaluator.evaluate_hand(&hand);
println!("Hand rank: {:?}", hand_value.rank);
```
## Bot Testing Capabilities
This framework provides specialized capabilities for poker bot testing and development:
### Automated Bot Testing
- **Standardized Evaluation**: Consistent hand evaluation across both Cactus Kev and Supersonic evaluators
- **Performance Benchmarking**: Fast evaluation for large-scale bot performance testing
- **Range Analysis**: Efficient hand range evaluation for bot strategy analysis
- **Decision Tree Testing**: Quick hand strength calculation for bot decision trees
### Dual Evaluator Support
- **Cactus Kev**: Compact ~100 KB tables with prime-product hashing — ideal for memory-constrained environments
- **Supersonic**: High-throughput ~124 MB LUT trie with O(n) array lookups — fastest for bulk evaluation
- **Algorithmic Fallback**: Rule-based evaluator serves as correctness oracle for validation
### Bot Development Features
- **Hole Card Analysis**: Fast evaluation of starting hand strength for pre-flop bots
- **Post-Flop Analysis**: Efficient board texture and hand strength analysis
- **Incremental Evaluation**: Multi-street hand evaluation for complex bot scenarios
- **Memory Efficient**: Optimized for bot testing environments with limited resources
## Algorithm Overview
This library provides **two hand evaluators** with different performance/memory tradeoffs:
### Cactus Kev Evaluator (compact)
Uses prime-product hashing into two small lookup tables (~100 KB total):
1. **Prime Product Hashing**: Each rank maps to a unique prime; the product of 5 primes uniquely identifies the hand
2. **Dual Lookup Tables**: 1,287 flush entries + 6,175 unsuited entries = 7,462 total (~30 KB)
3. **7-card Cache**: C(7,5)=21 enumeration with HashMap cache for amortized O(1) lookups
4. **Zero Collisions**: Validated against all 2,598,960 five-card hands
### Supersonic Evaluator (high-throughput)
Uses a pre-computed LUT trie (~124 MB) for O(n) array lookups:
1. **Trie Structure**: 32,487,834 `u32` entries organized in pages of 53 (one per card + base)
2. **Direct Lookup**: Follow `hand_ranks[p + card_index + 1]` for each card — no enumeration needed
3. **Packed Hand Rank**: 16-bit format (category + equivalency class) for compact result representation
4. **Best for Bulk**: Fastest evaluator for large-scale simulations and batch evaluation
### Table Generation
Lookup tables are generated automatically on first use and persisted to disk:
- **Cactus Kev**: Small tables (~100 KB) generated in-memory from prime products
- **Supersonic**: Large LUT trie (~124 MB) loaded from pre-generated binary file
## Hand Types
The evaluator recognizes all standard poker hand types:
| Hand Type | Description | Example |
|-----------|-------------|---------|
| Straight Flush | Five cards in sequence, same suit | A♠ K♠ Q♠ J♠ T♠ |
| Four of a Kind | Four cards of same rank | A♠ A♥ A♦ A♣ K♦ |
| Full House | Three of a kind + one pair | K♠ K♥ K♦ Q♠ Q♥ |
| Flush | Five cards of same suit | A♠ J♠ 8♠ 5♠ 2♠ |
| Straight | Five cards in sequence | A♦ K♣ Q♥ J♠ T♦ |
| Three of a Kind | Three cards of same rank | Q♠ Q♥ Q♦ A♣ 7♦ |
| Two Pair | Two different pairs | J♠ J♥ 7♦ 7♣ A♦ |
| One Pair | Two cards of same rank | A♠ A♥ K♦ Q♣ 7♦ |
| High Card | No matching cards | A♠ K♥ Q♦ J♣ 9♦ |
## Bot Testing Examples
### Texas Hold'em Bot Analysis
```rust
use holdem_core::hand_evaluator::LookupHandEvaluator;
use holdem_core::api::{card::Card, hand::Hand};
let evaluator = LookupHandEvaluator::new().unwrap();
// Bot analyzes hole cards + flop for decision making
let hole_card1 = Card::from_string("As").unwrap().index() as u32;
let hole_card2 = Card::from_string("Ks").unwrap().index() as u32;
let mut board = Hand::new();
board.add_card(Card::from_string("Td").unwrap()).unwrap();
board.add_card(Card::from_string("Jc").unwrap()).unwrap();
board.add_card(Card::from_string("Qh").unwrap()).unwrap();
// Bot evaluates complete hand strength
let hand_strength = evaluator.rank_hand_with_hole_cards(hole_card1, hole_card2, &board);
println!("Hand strength after flop: {}", hand_strength);
// Bot uses this for post-flop decision making
if hand_strength < 2000 { // Strong hand
println!("Bot: Continuing with strong hand");
}
```
### Bot Range Analysis
```rust
use holdem_core::hand_evaluator::LookupHandEvaluator;
use holdem_core::api::card::Card;
let evaluator = LookupHandEvaluator::new().unwrap();
// Bot analyzes range of starting hands for pre-flop strategy
let premium_hands = vec![
(Card::from_string("AA").unwrap(), Card::from_string("KK").unwrap()),
(Card::from_string("QQ").unwrap(), Card::from_string("JJ").unwrap()),
(Card::from_string("AK").unwrap(), Card::from_string("AQ").unwrap()),
];
for (card1, card2) in premium_hands {
let mut hand = Hand::new();
hand.add_card(card1).unwrap();
hand.add_card(card2).unwrap();
let strength = evaluator.rank_hand(&hand);
println!("Bot range analysis - {}: {}", hand.to_string(), strength);
}
```
## Advanced Usage
### 7-Card Hand Evaluation for Bot Testing
```rust
use holdem_core::hand_evaluator::LookupHandEvaluator;
use holdem_core::api::card::Card;
let evaluator = LookupHandEvaluator::new().unwrap();
// Texas Hold'em complete hand: 2 hole cards + 5 community cards
let hole_cards = [
Card::from_string("As").unwrap().index(),
Card::from_string("Ks").unwrap().index(),
];
let community_cards = [
Card::from_string("Td").unwrap().index(),
Card::from_string("Jc").unwrap().index(),
Card::from_string("Qh").unwrap().index(),
Card::from_string("9s").unwrap().index(),
Card::from_string("2d").unwrap().index(),
];
// Bot evaluates best possible hand from all cards
let all_cards: Vec<u32> = hole_cards.iter().chain(community_cards.iter()).cloned().collect();
let best_rank = evaluator.rank_hand7(&all_cards);
println!("Bot best hand rank: {}", best_rank);
```
## Testing
Run the comprehensive test suite:
```bash
cargo test
```
Run performance benchmarks:
```bash
cargo test --release hand_eval_integration_test -- --nocapture
```
## Simulation Testbed
The `holdem_sim` binary provides a CLI for running poker simulations with configurable bots, game types, and formats. It supports cash games, Sit & Go (SNG) tournaments, and Multi-Table Tournaments (MTT).
### Running Simulations
```bash
# Run a cash game simulation
cargo run --bin holdem_sim -- holdem_core/examples/configs/cash_game.toml
# Run with a specific seed for reproducibility
cargo run --bin holdem_sim -- holdem_core/examples/configs/cash_game.toml --seed 42
# Override the number of hands
cargo run --bin holdem_sim -- holdem_core/examples/configs/cash_game.toml --hands 5000
```
### Example Configuration (Cash Game)
```toml
[game]
game_type = "Cash"
num_seats = 6
small_blind = 10
big_blind = 20
ante = 0
starting_chips = 10000
num_hands = 1000
[game.bet_limit]
type = "no_limit"
min_raise = 20
[[game.bots]]
bot_type = "call_bot"
name = "Alice"
[[game.bots]]
bot_type = "fold_bot"
name = "Bob"
[[game.bots]]
bot_type = "random_bot"
name = "Charlie"
```
Example configs are available in [`holdem_core/examples/configs/`](holdem_core/examples/configs/):
- [`cash_game.toml`](holdem_core/examples/configs/cash_game.toml) — 6-max NLHE cash game
- [`sng_tournament.toml`](holdem_core/examples/configs/sng_tournament.toml) — 9-seat Sit & Go
- [`mtt_tournament.toml`](holdem_core/examples/configs/mtt_tournament.toml) — Multi-table tournament
### Built-in Bots
| Bot | Description |
|-----|-------------|
| `call_bot` | Calls every bet, never raises or folds |
| `fold_bot` | Folds whenever facing a bet, otherwise checks |
| `raise_bot` | Raises with configurable aggression thresholds |
| `random_bot` | Takes random legal actions with configurable tendencies |
### Example Output
```
=== Simulation Results ===
Hands played: 1000
Player Statistics:
Alice (call_bot)
Hands: 1000 | VPIP: 100.0% | PFR: 0.0% | Win: $45,230
Bob (fold_bot)
Hands: 1000 | VPIP: 0.0% | PFR: 0.0% | Win: -$32,100
Charlie (random_bot)
Hands: 1000 | VPIP: 67.3% | PFR: 22.1% | Win: -$13,130
```
## Mathematical Foundation
### Cactus Kev — Perfect Hash Algorithm
The Cactus Kev evaluator uses prime-product hashing:
```
Hash = prime(rank₁) × prime(rank₂) × ... × prime(rank₅)
Index = Hash % TABLE_SIZE
Rank = TABLE[Index]
```
Each rank maps to a unique prime (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41), so the product of 5 primes uniquely identifies the hand pattern.
### Supersonic — LUT Trie Algorithm
The Supersonic evaluator uses a pre-computed trie of 32.5M `u32` entries:
```
p = INITIAL_STATE (page 1 base)
for each card:
p = hand_ranks[p + card_index + 1]
rank = p // (for 7-card hands)
```
Each step is a single array lookup — no hashing, no enumeration, no branching.
## References
- **Cactus Kev**: Perfect hash algorithm for 5-card poker hand evaluation
- **Supersonic**: LUT trie evaluator for high-throughput hand evaluation
- **Poker Standards**: Standard poker hand ranking rules
- **Poker Testbed**: Framework designed for automated bot testing and analysis
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Areas for improvement:
- Hardware acceleration (SIMD optimizations)
- Additional poker variants (Omaha, Stud, etc.)
- Memory-mapped table loading
- Distributed table generation
- Advanced benchmarking tools
## Support
For questions, issues, or contributions, please:
1. Check existing documentation
2. Review test cases for usage examples
3. Open GitHub issues for bugs or feature requests
4. Submit pull requests with comprehensive tests
---
**Performance Note**: The Cactus Kev evaluator generates its small lookup tables (~100 KB) in-memory on first use. The Supersonic evaluator requires a pre-generated ~124 MB LUT file loaded at startup.