configurable strategy

This commit is contained in:
Jeff Wu 2016-03-20 12:40:27 -07:00
parent 931a7d73ad
commit e49cb29592
2 changed files with 45 additions and 18 deletions

View file

@ -39,12 +39,26 @@ fn main() {
let program = args[0].clone(); let program = args[0].clone();
let mut opts = Options::new(); let mut opts = Options::new();
opts.optopt("l", "loglevel", "Log level, one of 'trace', 'debug', 'info', 'warn', and 'error'", "LOGLEVEL"); opts.optopt("l", "loglevel",
opts.optopt("n", "ntrials", "Number of games to simulate", "NTRIALS"); "Log level, one of 'trace', 'debug', 'info', 'warn', and 'error'",
opts.optopt("t", "nthreads", "Number of threads to use for simulation", "NTHREADS"); "LOGLEVEL");
opts.optopt("s", "seed", "Seed for PRNG", "SEED"); opts.optopt("n", "ntrials",
opts.optopt("p", "nplayers", "Number of players", "NPLAYERS"); "Number of games to simulate",
opts.optflag("h", "help", "Print this help menu"); "NTRIALS");
opts.optopt("t", "nthreads",
"Number of threads to use for simulation",
"NTHREADS");
opts.optopt("s", "seed",
"Seed for PRNG",
"SEED");
opts.optopt("p", "nplayers",
"Number of players",
"NPLAYERS");
opts.optopt("g", "strategy",
"Which strategy to use. One of 'random' and 'cheat'",
"STRATEGY");
opts.optflag("h", "help",
"Print this help menu");
let matches = match opts.parse(&args[1..]) { let matches = match opts.parse(&args[1..]) {
Ok(m) => { m } Ok(m) => { m }
Err(f) => { Err(f) => {
@ -92,7 +106,7 @@ fn main() {
_ => { panic!("There should be 2 to 5 players, not {}", n_players); } _ => { panic!("There should be 2 to 5 players, not {}", n_players); }
}; };
let opts = game::GameOptions { let game_opts = game::GameOptions {
num_players: n_players, num_players: n_players,
hand_size: hand_size, hand_size: hand_size,
num_hints: 8, num_hints: 8,
@ -101,11 +115,22 @@ fn main() {
allow_empty_hints: false, allow_empty_hints: false,
}; };
// TODO: make this configurable let strategy_str : &str = &matches.opt_str("g").unwrap_or("cheat".to_string());
// let strategy_config = strategies::examples::RandomStrategyConfig { let strategy_config : Box<simulator::GameStrategyConfig + Sync> = match strategy_str {
// hint_probability: 0.4, "random" => {
// play_probability: 0.2, Box::new(strategies::examples::RandomStrategyConfig {
// }; hint_probability: 0.4,
let strategy_config = strategies::cheating::CheatingStrategyConfig::new(); play_probability: 0.2,
simulator::simulate(&opts, &strategy_config, seed, n, n_threads); }) as Box<simulator::GameStrategyConfig + Sync>
},
"cheat" => {
Box::new(strategies::cheating::CheatingStrategyConfig::new())
as Box<simulator::GameStrategyConfig + Sync>
},
_ => {
print_usage(&program, opts);
panic!("Unexpected strategy argument {}", strategy_str);
},
};
simulator::simulate(&game_opts, strategy_config, seed, n, n_threads);
} }

View file

@ -1,9 +1,10 @@
use rand::{self, Rng}; use rand::{self, Rng};
use game::*;
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
use crossbeam; use crossbeam;
use game::*;
// Traits to implement for any valid Hanabi strategy // Traits to implement for any valid Hanabi strategy
// Represents the strategy of a given player // Represents the strategy of a given player
@ -118,9 +119,9 @@ impl fmt::Display for Histogram {
} }
} }
pub fn simulate<T>( pub fn simulate<T: ?Sized>(
opts: &GameOptions, opts: &GameOptions,
strat_config: &T, strat_config: Box<T>,
first_seed_opt: Option<u32>, first_seed_opt: Option<u32>,
n_trials: u32, n_trials: u32,
n_threads: u32, n_threads: u32,
@ -128,6 +129,7 @@ pub fn simulate<T>(
let first_seed = first_seed_opt.unwrap_or(rand::thread_rng().next_u32()); let first_seed = first_seed_opt.unwrap_or(rand::thread_rng().next_u32());
let strat_config_ref = &strat_config;
crossbeam::scope(|scope| { crossbeam::scope(|scope| {
let mut join_handles = Vec::new(); let mut join_handles = Vec::new();
for i in 0..n_threads { for i in 0..n_threads {
@ -146,7 +148,7 @@ pub fn simulate<T>(
i, seed-start, histogram.average() i, seed-start, histogram.average()
); );
} }
let score = simulate_once(&opts, strat_config.initialize(&opts), Some(seed)); let score = simulate_once(&opts, strat_config_ref.initialize(&opts), Some(seed));
histogram.insert(score); histogram.insert(score);
if score != 25 { non_perfect_seeds.push((score, seed)); } if score != 25 { non_perfect_seeds.push((score, seed)); }
} }