make rng seedable

This commit is contained in:
Jeff Wu 2016-03-13 11:28:26 -07:00
parent 02ffb781b3
commit 6184fcd914
3 changed files with 50 additions and 29 deletions

View file

@ -1,4 +1,4 @@
use rand::{self, Rng}; use rand::{self, Rng, SeedableRng};
use std::collections::HashMap; use std::collections::HashMap;
use std::fmt; use std::fmt;
@ -49,10 +49,6 @@ impl fmt::Display for Card {
pub type Cards = Vec<Card>; pub type Cards = Vec<Card>;
pub type CardsInfo = Vec<CardInfo>; pub type CardsInfo = Vec<CardInfo>;
fn shuffle<T>(vec: &mut Vec<T>) {
rand::thread_rng().shuffle(&mut vec[..]);
}
#[derive(Debug)] #[derive(Debug)]
pub struct Firework { pub struct Firework {
pub color: Color, pub color: Color,
@ -293,7 +289,7 @@ impl PlayerState {
} }
} }
fn new_deck() -> Cards { fn new_deck(seed: u32) -> Cards {
let mut deck: Cards = Cards::new(); let mut deck: Cards = Cards::new();
for color in COLORS.iter() { for color in COLORS.iter() {
@ -304,7 +300,9 @@ fn new_deck() -> Cards {
} }
} }
}; };
shuffle(&mut deck);
rand::ChaChaRng::from_seed(&[seed]).shuffle(&mut deck[..]);
trace!("Created deck: {:?}", deck); trace!("Created deck: {:?}", deck);
deck deck
} }
@ -334,14 +332,14 @@ pub struct BoardState {
pub deckless_turns_remaining: u32, pub deckless_turns_remaining: u32,
} }
impl BoardState { impl BoardState {
pub fn new(opts: &GameOptions) -> BoardState { pub fn new(opts: &GameOptions, seed: u32) -> BoardState {
let mut fireworks : HashMap<Color, Firework> = HashMap::new(); let mut fireworks : HashMap<Color, Firework> = HashMap::new();
for color in COLORS.iter() { for color in COLORS.iter() {
fireworks.insert(color, Firework::new(color)); fireworks.insert(color, Firework::new(color));
} }
BoardState { BoardState {
deck: new_deck(), deck: new_deck(seed),
fireworks: fireworks, fireworks: fireworks,
discard: Discard::new(), discard: Discard::new(),
num_players: opts.num_players, num_players: opts.num_players,
@ -528,8 +526,8 @@ impl fmt::Display for GameState {
pub type Score = u32; pub type Score = u32;
impl GameState { impl GameState {
pub fn new(opts: &GameOptions) -> GameState { pub fn new(opts: &GameOptions, seed: u32) -> GameState {
let mut board = BoardState::new(opts); let mut board = BoardState::new(opts, seed);
let mut player_states : HashMap<Player, PlayerState> = HashMap::new(); let mut player_states : HashMap<Player, PlayerState> = HashMap::new();
for i in 0..opts.num_players { for i in 0..opts.num_players {

View file

@ -28,8 +28,8 @@ impl log::Log for SimpleLogger {
fn main() { fn main() {
log::set_logger(|max_log_level| { log::set_logger(|max_log_level| {
//max_log_level.set(log::LogLevelFilter::Trace); max_log_level.set(log::LogLevelFilter::Trace);
max_log_level.set(log::LogLevelFilter::Info); // max_log_level.set(log::LogLevelFilter::Info);
Box::new(SimpleLogger) Box::new(SimpleLogger)
}).unwrap(); }).unwrap();
@ -42,15 +42,6 @@ fn main() {
let n = 1000; let n = 1000;
// simulator::simulate(&opts, &strategies::examples::AlwaysDiscard, n); // simulator::simulate(&opts, &strategies::examples::AlwaysDiscard, n);
// simulator::simulate_symmetric(&opts, strategies::examples::AlwaysPlayConfig, n); // simulator::simulate_symmetric(&opts, strategies::examples::AlwaysPlayConfig, n);
// simulator::simulate(
// &opts,
// &vec![
// Box::new(strategies::examples::AlwaysPlayConfig),
// Box::new(strategies::examples::AlwaysPlayConfig),
// Box::new(strategies::examples::AlwaysPlayConfig),
// Box::new(strategies::examples::AlwaysPlayConfig),
// ],
// n);
// simulator::simulate_symmetric( // simulator::simulate_symmetric(
// &opts, // &opts,
// strategies::examples::RandomStrategyConfig { // strategies::examples::RandomStrategyConfig {
@ -59,9 +50,13 @@ fn main() {
// }, // },
// n // n
// ); // );
simulator::simulate_symmetric( // simulator::simulate_symmetric(
&opts, // &opts,
// strategies::cheating::CheatingStrategyConfig::new(),
// n
// );
simulator::simulate_symmetric_once(
&opts, Some(993),
strategies::cheating::CheatingStrategyConfig::new(), strategies::cheating::CheatingStrategyConfig::new(),
n
); );
} }

View file

@ -1,3 +1,4 @@
use rand::{self, Rng};
use game::*; use game::*;
use std::collections::HashMap; use std::collections::HashMap;
@ -11,8 +12,19 @@ pub trait StrategyConfig {
fn initialize(&self, Player, &GameStateView) -> Box<Strategy>; fn initialize(&self, Player, &GameStateView) -> Box<Strategy>;
} }
pub fn simulate_once<'a>(opts: &GameOptions, strat_configs: &Vec<Box<StrategyConfig + 'a>>) -> Score { pub fn simulate_once<'a>(
let mut game = GameState::new(opts); opts: &GameOptions,
seed_opt: Option<u32>,
strat_configs: &Vec<Box<StrategyConfig + 'a>>
) -> Score {
let seed = if let Some(seed) = seed_opt {
seed
} else {
rand::thread_rng().next_u32()
};
let mut game = GameState::new(opts, seed);
assert_eq!(opts.num_players, (strat_configs.len() as u32)); assert_eq!(opts.num_players, (strat_configs.len() as u32));
@ -54,9 +66,12 @@ pub fn simulate_once<'a>(opts: &GameOptions, strat_configs: &Vec<Box<StrategyCon
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 _ in 0..n_trials { for seed in 0..n_trials {
let score = simulate_once(&opts, strat_configs); let score = simulate_once(&opts, Some(seed), strat_configs);
debug!("Scored: {:?}", score); debug!("Scored: {:?}", score);
if score != 25 {
info!("Seed with non-perfect score: {:?}", seed);
}
total_score += score; total_score += score;
} }
let average: f32 = (total_score as f32) / (n_trials as f32); let average: f32 = (total_score as f32) / (n_trials as f32);
@ -64,6 +79,19 @@ pub fn simulate<'a>(opts: &GameOptions, strat_configs: &Vec<Box<StrategyConfig +
average average
} }
pub fn simulate_symmetric_once<'a, S: StrategyConfig + Clone + 'a>(
opts: &GameOptions,
seed_opt: Option<u32>,
strat_config: S
) -> Score {
let mut strat_configs = Vec::new();
for _ in 0..opts.num_players {
strat_configs.push(Box::new(strat_config.clone()) as Box<StrategyConfig + 'a>);
}
simulate_once(opts, seed_opt, &strat_configs)
}
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 {
let mut strat_configs = Vec::new(); let mut strat_configs = Vec::new();
for _ in 0..opts.num_players { for _ in 0..opts.num_players {