use clap::{Parser, ValueEnum}; use crate::{ agents::{Diffuse, Human, MaximizerAgent, MinimizerAgent, Random, SimpleMinimax}, util::Player, }; #[derive(Parser, Debug)] #[command(about)] pub struct Cli { /// The agent that controls the Blue (opponent) player pub blue: AgentSelector, /// The agent that controls the Red (home) player #[arg(long, default_value = "human")] pub red: AgentSelector, /// If this is greater than one, repeat the game this many times and print a summary. /// Best used with --silent. #[arg(long, short, default_value = "0")] pub repeat: usize, /// If this is given, do not print boards. /// Good for bulk runs with --repeat, bad for human players. #[arg(long, short, default_value = "false")] pub silent: bool, } #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum)] pub enum AgentSelector { /// A human agent. Asks for input. Human, /// A random agent (very easy) Random, /// A simple extremum-chaser (easy) Minimax, /// A smarter extremum-chaser (medium) Diffuse, } impl AgentSelector { pub fn to_maxi(&self, player: Player) -> Box { match self { Self::Random => Box::new(Random::new(player)), Self::Minimax => Box::new(SimpleMinimax::new(player)), Self::Diffuse => Box::new(Diffuse::new(player)), Self::Human => Box::new(Human::new(player)), } } pub fn to_mini(&self, player: Player) -> Box { match self { Self::Random => Box::new(Random::new(player)), Self::Minimax => Box::new(SimpleMinimax::new(player)), Self::Diffuse => Box::new(Diffuse::new(player)), Self::Human => Box::new(Human::new(player)), } } } impl ToString for AgentSelector { fn to_string(&self) -> String { match self { Self::Random => "random", Self::Diffuse => "diffuse", Self::Minimax => "minimax", Self::Human => "human", } .to_string() } }