command line parsing
This commit is contained in:
parent
adaa513ff8
commit
7f5feacbc7
4 changed files with 73 additions and 27 deletions
6
Cargo.lock
generated
6
Cargo.lock
generated
|
@ -2,10 +2,16 @@
|
||||||
name = "rust_hanabi"
|
name = "rust_hanabi"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getopts"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.7"
|
version = "0.2.7"
|
||||||
|
|
|
@ -6,3 +6,4 @@ authors = ["Jeff Wu <wuthefwasthat@gmail.com>"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
rand = "*"
|
rand = "*"
|
||||||
log = "*"
|
log = "*"
|
||||||
|
getopts = "*"
|
||||||
|
|
81
src/main.rs
81
src/main.rs
|
@ -1,6 +1,7 @@
|
||||||
extern crate rand;
|
extern crate getopts;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
mod game;
|
mod game;
|
||||||
mod simulator;
|
mod simulator;
|
||||||
|
@ -10,13 +11,13 @@ mod strategies {
|
||||||
}
|
}
|
||||||
mod info;
|
mod info;
|
||||||
|
|
||||||
#[allow(unused_imports)]
|
use getopts::Options;
|
||||||
use log::LogLevel::{Trace, Debug, Info, Warn, Error};
|
use std::str::FromStr;
|
||||||
|
|
||||||
struct SimpleLogger;
|
struct SimpleLogger;
|
||||||
impl log::Log for SimpleLogger {
|
impl log::Log for SimpleLogger {
|
||||||
fn enabled(&self, metadata: &log::LogMetadata) -> bool {
|
fn enabled(&self, metadata: &log::LogMetadata) -> bool {
|
||||||
metadata.level() <= Debug
|
metadata.level() <= log::LogLevel::Trace
|
||||||
}
|
}
|
||||||
|
|
||||||
fn log(&self, record: &log::LogRecord) {
|
fn log(&self, record: &log::LogRecord) {
|
||||||
|
@ -26,37 +27,75 @@ impl log::Log for SimpleLogger {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fn print_usage(program: &str, opts: Options) {
|
||||||
|
print!("{}", opts.usage(&format!("Usage: {} [options]", program)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// TODO: make a binary with command line options
|
let args: Vec<String> = std::env::args().collect();
|
||||||
|
let program = args[0].clone();
|
||||||
|
|
||||||
|
let mut opts = Options::new();
|
||||||
|
opts.optopt("l", "loglevel", "Log level, one of 'trace', 'debug', 'info', 'warn', and 'error'", "LOGLEVEL");
|
||||||
|
opts.optopt("n", "ntrials", "Number of games to simulate", "NTRIALS");
|
||||||
|
opts.optopt("s", "seed", "Seed for PRNG (can only be used with n=1)", "SEED");
|
||||||
|
opts.optflag("h", "help", "Print this help menu");
|
||||||
|
let matches = match opts.parse(&args[1..]) {
|
||||||
|
Ok(m) => { m }
|
||||||
|
Err(f) => {
|
||||||
|
print_usage(&program, opts);
|
||||||
|
panic!(f.to_string())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if matches.opt_present("h") {
|
||||||
|
return print_usage(&program, opts);
|
||||||
|
}
|
||||||
|
if !matches.free.is_empty() {
|
||||||
|
return print_usage(&program, opts);
|
||||||
|
}
|
||||||
|
|
||||||
|
let log_level_str : &str = &matches.opt_str("l").unwrap_or("info".to_string());
|
||||||
|
let log_level = match log_level_str {
|
||||||
|
"trace" => { log::LogLevelFilter::Trace }
|
||||||
|
"debug" => { log::LogLevelFilter::Debug }
|
||||||
|
"info" => { log::LogLevelFilter::Info }
|
||||||
|
"warn" => { log::LogLevelFilter::Warn }
|
||||||
|
"error" => { log::LogLevelFilter::Error }
|
||||||
|
_ => { panic!("Unexpected log level argument {}", log_level_str); }
|
||||||
|
};
|
||||||
|
|
||||||
log::set_logger(|max_log_level| {
|
log::set_logger(|max_log_level| {
|
||||||
// max_log_level.set(log::LogLevelFilter::Trace);
|
max_log_level.set(log_level);
|
||||||
max_log_level.set(log::LogLevelFilter::Info);
|
|
||||||
Box::new(SimpleLogger)
|
Box::new(SimpleLogger)
|
||||||
}).unwrap();
|
}).unwrap();
|
||||||
|
|
||||||
|
let n = u32::from_str(&matches.opt_str("n").unwrap_or("1".to_string())).unwrap();
|
||||||
|
|
||||||
|
let seed = matches.opt_str("s").map(|seed_str| { u32::from_str(&seed_str).unwrap() });
|
||||||
|
|
||||||
|
// TODO: make these configurable
|
||||||
let opts = game::GameOptions {
|
let opts = game::GameOptions {
|
||||||
num_players: 4,
|
num_players: 4,
|
||||||
hand_size: 4,
|
hand_size: 4,
|
||||||
num_hints: 8,
|
num_hints: 8,
|
||||||
num_lives: 3,
|
num_lives: 3,
|
||||||
};
|
};
|
||||||
let n = 1000;
|
|
||||||
// simulator::simulate(&opts, &strategies::examples::AlwaysDiscard, n);
|
// TODO: make this configurable
|
||||||
// simulator::simulate_symmetric(&opts, strategies::examples::AlwaysPlayConfig, n);
|
// let strategy = strategies::examples::AlwaysPlayConfig;
|
||||||
// simulator::simulate_symmetric(
|
// let strategy = strategies::examples::RandomStrategyConfig {
|
||||||
// &opts,
|
|
||||||
// strategies::examples::RandomStrategyConfig {
|
|
||||||
// hint_probability: 0.4,
|
// hint_probability: 0.4,
|
||||||
// play_probability: 0.2,
|
// play_probability: 0.2,
|
||||||
// },
|
// };
|
||||||
// n
|
let strategy = strategies::cheating::CheatingStrategyConfig::new();
|
||||||
// );
|
if n == 1 {
|
||||||
simulator::simulate_symmetric(
|
simulator::simulate_symmetric_once(&opts, strategy, seed);
|
||||||
&opts,
|
} else {
|
||||||
strategies::cheating::CheatingStrategyConfig::new(),
|
simulator::simulate_symmetric(&opts, strategy, n);
|
||||||
n
|
}
|
||||||
);
|
|
||||||
// simulator::simulate_symmetric_once(
|
// simulator::simulate_symmetric_once(
|
||||||
// &opts, Some(999),
|
// &opts, Some(999),
|
||||||
// strategies::cheating::CheatingStrategyConfig::new(),
|
// strategies::cheating::CheatingStrategyConfig::new(),
|
||||||
|
|
|
@ -14,8 +14,8 @@ pub trait StrategyConfig {
|
||||||
|
|
||||||
pub fn simulate_once<'a>(
|
pub fn simulate_once<'a>(
|
||||||
opts: &GameOptions,
|
opts: &GameOptions,
|
||||||
|
strat_configs: &Vec<Box<StrategyConfig + 'a>>,
|
||||||
seed_opt: Option<u32>,
|
seed_opt: Option<u32>,
|
||||||
strat_configs: &Vec<Box<StrategyConfig + 'a>>
|
|
||||||
) -> Score {
|
) -> Score {
|
||||||
|
|
||||||
let seed = if let Some(seed) = seed_opt {
|
let seed = if let Some(seed) = seed_opt {
|
||||||
|
@ -69,7 +69,7 @@ pub fn simulate_once<'a>(
|
||||||
pub fn simulate<'a>(opts: &GameOptions, strat_configs: &Vec<Box<StrategyConfig + 'a>>, n_trials: u32) -> f32 {
|
pub fn simulate<'a>(opts: &GameOptions, strat_configs: &Vec<Box<StrategyConfig + 'a>>, n_trials: u32) -> f32 {
|
||||||
let mut total_score = 0;
|
let mut total_score = 0;
|
||||||
for seed in 0..n_trials {
|
for seed in 0..n_trials {
|
||||||
let score = simulate_once(&opts, Some(seed), strat_configs);
|
let score = simulate_once(&opts, strat_configs, Some(seed));
|
||||||
debug!("Scored: {:?}", score);
|
debug!("Scored: {:?}", score);
|
||||||
if score != 25 {
|
if score != 25 {
|
||||||
info!("Seed with non-perfect score: {:?}", seed);
|
info!("Seed with non-perfect score: {:?}", seed);
|
||||||
|
@ -83,15 +83,15 @@ pub fn simulate<'a>(opts: &GameOptions, strat_configs: &Vec<Box<StrategyConfig +
|
||||||
|
|
||||||
pub fn simulate_symmetric_once<'a, S: StrategyConfig + Clone + 'a>(
|
pub fn simulate_symmetric_once<'a, S: StrategyConfig + Clone + 'a>(
|
||||||
opts: &GameOptions,
|
opts: &GameOptions,
|
||||||
|
strat_config: S,
|
||||||
seed_opt: Option<u32>,
|
seed_opt: Option<u32>,
|
||||||
strat_config: S
|
|
||||||
) -> Score {
|
) -> Score {
|
||||||
|
|
||||||
let mut strat_configs = Vec::new();
|
let mut strat_configs = Vec::new();
|
||||||
for _ in 0..opts.num_players {
|
for _ in 0..opts.num_players {
|
||||||
strat_configs.push(Box::new(strat_config.clone()) as Box<StrategyConfig + 'a>);
|
strat_configs.push(Box::new(strat_config.clone()) as Box<StrategyConfig + 'a>);
|
||||||
}
|
}
|
||||||
simulate_once(opts, seed_opt, &strat_configs)
|
simulate_once(opts, &strat_configs, seed_opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn simulate_symmetric<'a, S: StrategyConfig + Clone + 'a>(opts: &GameOptions, strat_config: S, n_trials: u32) -> f32 {
|
pub fn simulate_symmetric<'a, S: StrategyConfig + Clone + 'a>(opts: &GameOptions, strat_config: S, n_trials: u32) -> f32 {
|
||||||
|
|
Loading…
Reference in a new issue