feat: refactor AlgorithmicEvaluator to stateless, add game engine module and holdem_sim CLI

- Refactor AlgorithmicEvaluator from stateful Arc<Evaluator> wrapper to
  pure stateless evaluator with zero-allocation construction
- Extract shared evaluation logic into pub(crate) methods, eliminating
  ~220 lines of duplicated code from Evaluator
- Add game module: table, hand runner, tournament, bots, config, stats
- Add holdem_sim CLI binary crate for running simulations
- Convert MathEvaluator to thread-safe singleton with Arc<Inner> pattern
- Replace heap-allocated combination generation with const-generics
  stack-based approach in AlgorithmicEvaluator::evaluate_n_card_hand
- Add thiserror 2 dependency for GameError derive
- Update docs: README, ACHIEVEMENTS, ROADMAP
This commit is contained in:
Jan-Peter von Hunnius 2026-05-18 15:12:34 +02:00
parent dd605e8a66
commit 17d0440c86
43 changed files with 12329 additions and 494 deletions

View file

@ -282,6 +282,82 @@ Run performance benchmarks:
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
### Perfect Hash Algorithm