Skip to main content

robot_master/
config.rs

1use std::path::PathBuf;
2
3use clap::{Parser, Subcommand};
4use robot_master_arena::{BoardSize, config::ArenaConfig};
5use v_utils::macros as v_macros;
6
7#[derive(Parser)]
8#[command(author, version = concat!(env!("CARGO_PKG_VERSION"), " (", env!("GIT_HASH"), ")"), about, long_about = None)]
9pub struct Cli {
10	#[clap(flatten)]
11	pub settings_flags: SettingsFlags,
12	#[clap(flatten)]
13	pub players: PlayerArgs,
14	#[command(subcommand)]
15	pub command: Commands,
16}
17#[derive(Clone, Debug, Parser)]
18pub struct PlayerArgs {
19	/// Player 1 (Cols) algorithm: manual/m, random/r, greedy/g, sadist/s
20	#[arg(short = 'a', long, default_value = "manual")]
21	pub player1: String,
22	/// Player 2 (Rows) algorithm: manual/m, random/r, greedy/g, sadist/s
23	#[arg(short = 'b', long, default_value = "random")]
24	pub player2: String,
25	/// Board size (5, 7, 9, or 11)
26	#[arg(short = 's', long, default_value = "5")]
27	pub size: BoardSize,
28	/// Hide opponent's hand (information-hidden mode)
29	#[arg(long, default_value = "false")]
30	pub hide: bool,
31	/// Directory containing .onnx model files
32	#[arg(long, default_value = "./models")]
33	pub models_dir: PathBuf,
34}
35#[derive(Clone, Debug, Parser)]
36pub struct TrainArgs {
37	/// Include the git hash in the run ID (fully pins to exact build; fragments cache across commits)
38	#[arg(long)]
39	pub exact_generation: bool,
40	/// Number of selfplay → train → export iterations
41	#[arg(long, default_value = "20")]
42	pub iterations: u32,
43	/// Self-play games per iteration
44	#[arg(long, default_value = "200")]
45	pub games: u32,
46	/// Gumbel simulations per move during self-play
47	#[arg(long, default_value = "64")]
48	pub sims: u32,
49	/// Board size (must match the selfplay binary and model architecture)
50	#[arg(long, default_value = "5")]
51	pub size: u32,
52	/// Pass --force-cpu to selfplay (sequential rayon, faster at 5×5/7×7).
53	#[arg(long)]
54	pub force_cpu: bool,
55	/// Hide opponent's hand (information-hidden mode).
56	#[arg(long)]
57	pub hide: bool,
58}
59#[derive(Subcommand)]
60pub enum Commands {
61	/// Play the game in the terminal
62	Tui,
63	/// Play the game with a graphical interface
64	Gui {
65		/// Enable music and sound effects
66		#[arg(long, default_value = "false")]
67		sound: bool,
68	},
69	/// Arena: tournaments and data management
70	Arena {
71		/// Filter players by grepping these patterns against known IDs. If empty, all players.
72		#[arg(short, long, value_delimiter = ',')]
73		select: Vec<String>,
74		/// Run an ephemeral tournament with these player specs (e.g. `rollout|v50 rollout|g200`).
75		/// Bypasses the ratings database entirely - no prior ratings loaded, nothing saved.
76		/// Mutually exclusive with --select.
77		#[arg(long, value_delimiter = ',')]
78		no_priors: Vec<String>,
79		#[command(subcommand)]
80		command: ArenaCommands,
81	},
82	/// Train a neural network model (AlphaZero selfplay → train → export loop)
83	Train {
84		#[command(subcommand)]
85		arch: TrainArch,
86	},
87	//DO: `site` command that starts the leptos server
88}
89
90#[derive(Subcommand)]
91pub enum TrainArch {
92	/// ResNet CNN architecture
93	Cnn {
94		#[clap(flatten)]
95		args: TrainArgs,
96		/// Supervised pre-training spec (e.g. `rollout|v50`). Controls both:
97		/// selfplay data generation (uses this bot until NN beats it >68% over 32 games),
98		/// and eval matches run every 10 versions to detect the threshold.
99		/// If omitted, starts NN selfplay immediately with no eval.
100		#[arg(long)]
101		supervise: Option<String>,
102	},
103	/// Transformer architecture
104	Transformer {
105		#[clap(flatten)]
106		args: TrainArgs,
107	},
108}
109
110#[derive(Subcommand)]
111pub enum ArenaCommands {
112	/// Run a tournament
113	Tourney {
114		#[command(subcommand)]
115		mode: TourneyMode,
116		/// Output results as JSON to stdout (progress and status remain on stderr).
117		#[arg(long)]
118		json: bool,
119	},
120	/// Player data management
121	Players {
122		#[command(subcommand)]
123		command: PlayersCommands,
124	},
125}
126
127#[derive(Subcommand)]
128pub enum TourneyMode {
129	/// True FIDE Swiss: 1 game/pairing, pair within score groups, runs N full brackets
130	Swiss {
131		/// Number of full Swiss brackets to run
132		#[arg(default_value = "10")]
133		cycles: usize,
134		/// Number of threads (0 = all cores)
135		#[arg(short, long, default_value = "0")]
136		threads: usize,
137	},
138	/// Rating-based: weighted-random pairing by ELO proximity, ceil(target_rounds / threads) cycles
139	Rating {
140		/// Total games to play (split across cycles of `threads` games each)
141		#[arg(default_value = "100")]
142		target_rounds: usize,
143		/// Number of threads (0 = all cores)
144		#[arg(short, long, default_value = "0")]
145		threads: usize,
146	},
147	/// Single-elimination: pair by ELO proximity, winners advance, repeat for N cycles
148	Elimination {
149		/// Number of full elimination brackets to run
150		#[arg(default_value = "10")]
151		cycles: usize,
152		/// Number of threads (0 = all cores)
153		#[arg(short, long, default_value = "0")]
154		threads: usize,
155	},
156	/// Round-robin: every player plays every other exactly once per sweep, repeat for N sweeps
157	RoundRobin {
158		/// Number of full round-robin sweeps to run
159		#[arg(default_value = "3")]
160		cycles: usize,
161		/// Number of threads (0 = all cores)
162		#[arg(short, long, default_value = "0")]
163		threads: usize,
164	},
165}
166
167#[derive(Subcommand)]
168pub enum PlayersCommands {
169	/// Register player algorithms (e.g. `rollout|800`, `random`, `onnx:model_v5|g200|s5|hh`). Also auto-registers any missing default variants.
170	New {
171		/// Player specs: algo names with optional sim counts (e.g. `rollout|800`, `greedy`, `onnx:model_v5|g400`)
172		players: Vec<String>,
173		/// Constrain to specific board sizes, e.g. `5,7`. Required for onnx bots; ignored for rule-based bots.
174		#[arg(long, value_delimiter = ',')]
175		sizes: Vec<u8>,
176		/// Constrain to a specific hide mode. Optional; omit to support both modes.
177		#[arg(long)]
178		hide: Option<bool>,
179	},
180	/// List all players and their ratings
181	List,
182	/// Reset ratings to default (all if no players filter, otherwise only matched)
183	ResetRatings,
184	/// Remove players from the database entirely
185	Nuke,
186}
187
188#[derive(Clone, Debug, Default, v_macros::LiveSettings, v_macros::MyConfigPrimitives, v_macros::Settings)]
189pub struct Config {
190	#[serde(default)]
191	pub arena: ArenaConfig,
192}