#[cfg(not(target_env = "msvc"))]
#[global_allocator]
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
#[cfg(not(target_env = "msvc"))]
#[allow(non_upper_case_globals)]
#[unsafe(no_mangle)]
pub static malloc_conf: &[u8; 40] = b"dirty_decay_ms:1000,muzzy_decay_ms:1000\0";
mod arena;
mod budget;
mod common;
mod holdem;
mod icm;
mod ohh;
mod omaha;
mod tui;
use clap::{Parser, Subcommand};
use common::TracingArgs;
#[derive(Parser)]
#[command(name = "rsp", about = "A poker toolkit")]
struct Cli {
#[command(flatten)]
tracing: TracingArgs,
#[arg(long, global = true)]
budget: Option<String>,
#[command(subcommand)]
command: Commands,
}
#[derive(Subcommand)]
enum Commands {
Holdem(holdem::HoldemArgs),
Arena(arena::ArenaArgs),
Omaha(omaha::OmahaArgs),
Icm(icm::IcmArgs),
Ohh(ohh::OhhArgs),
}
#[derive(Debug, thiserror::Error)]
enum CliError {
#[error(transparent)]
Holdem(#[from] holdem::HoldemError),
#[error(transparent)]
Arena(#[from] arena::ArenaError),
#[error(transparent)]
Omaha(#[from] omaha::OmahaError),
#[error(transparent)]
Icm(#[from] icm::MatusowMeltdown),
#[error(transparent)]
Ohh(#[from] ohh::OhhError),
#[error(transparent)]
Budget(#[from] budget::BudgetError),
}
const WORKER_STACK_SIZE: usize = 47 * 1024 * 1024;
fn main() -> Result<(), CliError> {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.thread_stack_size(WORKER_STACK_SIZE)
.build()
.expect("failed to build tokio runtime");
runtime.block_on(async_main())
}
async fn async_main() -> Result<(), CliError> {
let cli = Cli::parse();
cli.tracing.init_tracing();
match cli.command {
Commands::Holdem(args) => holdem::run(args)?,
Commands::Arena(args) => {
let default_budget = budget::effective_budget(cli.budget.as_deref())?;
arena::run(args, default_budget).await?
}
Commands::Omaha(args) => omaha::run(args)?,
Commands::Icm(args) => icm::run(args).await?,
Commands::Ohh(args) => ohh::run(args)?,
}
Ok(())
}