feat: hand history logging, tournament series, MTT consolidation, Meerkat API
Major changes: - Add hand history module (iPoker format) with HandHistoryLogger - Add run_sng_series() for multi-tournament aggregate statistics - Fix MTT table consolidation deadlock (sub-minimum-player tables) - Add Meerkat-compatible convenience methods on Action and GameInfo - Add custom blind levels, prize structures, auto-rebuy to GameConfig - Add SngSeriesResult/SngPlayerSeriesResult for series tracking - Add Tournament::winner(), tables_mut(), shuffle_seats() Review fixes: - Fix TOML prizes field ordering (must precede [[game.blind_levels]]) - Add sensible serde defaults for small_blind (10) and big_blind (20) - Fix prize assignment in run_sng_series (use raw_placement directly) - Handle hand history filename collisions with suffixed retry - Add debug_assert guard on collect_hand_history_data double-consumption
This commit is contained in:
parent
9dfd9c3ee3
commit
c041cde3fe
18 changed files with 4601 additions and 208 deletions
|
|
@ -17,7 +17,7 @@ use clap::Parser;
|
|||
|
||||
use holdem_core::game::bot_factory::create_bot;
|
||||
use holdem_core::game::config::SimulationConfig;
|
||||
use holdem_core::game::simulation::run_cash_game;
|
||||
use holdem_core::game::simulation::{run_cash_game, run_sng_series};
|
||||
use holdem_core::game::stats::SimulationStats;
|
||||
use holdem_core::game::tournament::{GameType, Tournament};
|
||||
use holdem_core::game::types::PlayerId;
|
||||
|
|
@ -75,11 +75,16 @@ fn main() {
|
|||
game_config.num_hands = hands;
|
||||
}
|
||||
|
||||
// Run simulation based on game type
|
||||
// Run simulation based on game type and number of tournaments
|
||||
match game_config.game_type {
|
||||
GameType::Cash => run_cash_simulation(&game_config),
|
||||
GameType::SitAndGo => run_tournament_simulation(&game_config),
|
||||
GameType::MultiTableTournament => run_tournament_simulation(&game_config),
|
||||
GameType::SitAndGo | GameType::MultiTableTournament => {
|
||||
if game_config.num_tournaments > 1 {
|
||||
run_tournament_series_simulation(&game_config, game_config.num_tournaments);
|
||||
} else {
|
||||
run_tournament_simulation(&game_config);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -197,3 +202,35 @@ fn run_tournament_simulation(config: &holdem_core::game::config::GameConfig) {
|
|||
|
||||
println!("{}", stats.summary(config.buy_in));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Tournament Series (SNG or MTT)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
fn run_tournament_series_simulation(config: &holdem_core::game::config::GameConfig, num_tournaments: u32) {
|
||||
let game_type_name = match config.game_type {
|
||||
GameType::SitAndGo => "SNG",
|
||||
GameType::MultiTableTournament => "MTT",
|
||||
GameType::Cash => "Cash",
|
||||
};
|
||||
println!("=== {} Tournament Series ===", game_type_name);
|
||||
println!("Tournaments: {}", num_tournaments);
|
||||
println!("Buy-in: {}", config.buy_in);
|
||||
println!("Starting chips: {}", config.starting_chips);
|
||||
println!("Blinds: {}/{}", config.small_blind, config.big_blind);
|
||||
println!("Players: {}", config.bots.len());
|
||||
if config.game_type == GameType::MultiTableTournament {
|
||||
println!("Tables: {}", config.num_tables);
|
||||
}
|
||||
if let Some(seed) = config.seed {
|
||||
println!("Seed: {}", seed);
|
||||
}
|
||||
println!();
|
||||
|
||||
let result = run_sng_series(config, num_tournaments).unwrap_or_else(|e| {
|
||||
eprintln!("Tournament series error: {}", e);
|
||||
std::process::exit(1);
|
||||
});
|
||||
|
||||
println!("{}", result.summary());
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue