make rng seedable
This commit is contained in:
parent
02ffb781b3
commit
6184fcd914
3 changed files with 50 additions and 29 deletions
20
src/game.rs
20
src/game.rs
|
@ -1,4 +1,4 @@
|
|||
use rand::{self, Rng};
|
||||
use rand::{self, Rng, SeedableRng};
|
||||
use std::collections::HashMap;
|
||||
use std::fmt;
|
||||
|
||||
|
@ -49,10 +49,6 @@ impl fmt::Display for Card {
|
|||
pub type Cards = Vec<Card>;
|
||||
pub type CardsInfo = Vec<CardInfo>;
|
||||
|
||||
fn shuffle<T>(vec: &mut Vec<T>) {
|
||||
rand::thread_rng().shuffle(&mut vec[..]);
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Firework {
|
||||
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();
|
||||
|
||||
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);
|
||||
deck
|
||||
}
|
||||
|
@ -334,14 +332,14 @@ pub struct BoardState {
|
|||
pub deckless_turns_remaining: u32,
|
||||
}
|
||||
impl BoardState {
|
||||
pub fn new(opts: &GameOptions) -> BoardState {
|
||||
pub fn new(opts: &GameOptions, seed: u32) -> BoardState {
|
||||
let mut fireworks : HashMap<Color, Firework> = HashMap::new();
|
||||
for color in COLORS.iter() {
|
||||
fireworks.insert(color, Firework::new(color));
|
||||
}
|
||||
|
||||
BoardState {
|
||||
deck: new_deck(),
|
||||
deck: new_deck(seed),
|
||||
fireworks: fireworks,
|
||||
discard: Discard::new(),
|
||||
num_players: opts.num_players,
|
||||
|
@ -528,8 +526,8 @@ impl fmt::Display for GameState {
|
|||
pub type Score = u32;
|
||||
|
||||
impl GameState {
|
||||
pub fn new(opts: &GameOptions) -> GameState {
|
||||
let mut board = BoardState::new(opts);
|
||||
pub fn new(opts: &GameOptions, seed: u32) -> GameState {
|
||||
let mut board = BoardState::new(opts, seed);
|
||||
|
||||
let mut player_states : HashMap<Player, PlayerState> = HashMap::new();
|
||||
for i in 0..opts.num_players {
|
||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -28,8 +28,8 @@ impl log::Log for SimpleLogger {
|
|||
|
||||
fn main() {
|
||||
log::set_logger(|max_log_level| {
|
||||
//max_log_level.set(log::LogLevelFilter::Trace);
|
||||
max_log_level.set(log::LogLevelFilter::Info);
|
||||
max_log_level.set(log::LogLevelFilter::Trace);
|
||||
// max_log_level.set(log::LogLevelFilter::Info);
|
||||
Box::new(SimpleLogger)
|
||||
}).unwrap();
|
||||
|
||||
|
@ -42,15 +42,6 @@ fn main() {
|
|||
let n = 1000;
|
||||
// simulator::simulate(&opts, &strategies::examples::AlwaysDiscard, 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(
|
||||
// &opts,
|
||||
// strategies::examples::RandomStrategyConfig {
|
||||
|
@ -59,9 +50,13 @@ fn main() {
|
|||
// },
|
||||
// n
|
||||
// );
|
||||
simulator::simulate_symmetric(
|
||||
&opts,
|
||||
// simulator::simulate_symmetric(
|
||||
// &opts,
|
||||
// strategies::cheating::CheatingStrategyConfig::new(),
|
||||
// n
|
||||
// );
|
||||
simulator::simulate_symmetric_once(
|
||||
&opts, Some(993),
|
||||
strategies::cheating::CheatingStrategyConfig::new(),
|
||||
n
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use rand::{self, Rng};
|
||||
use game::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
|
@ -11,8 +12,19 @@ pub trait StrategyConfig {
|
|||
fn initialize(&self, Player, &GameStateView) -> Box<Strategy>;
|
||||
}
|
||||
|
||||
pub fn simulate_once<'a>(opts: &GameOptions, strat_configs: &Vec<Box<StrategyConfig + 'a>>) -> Score {
|
||||
let mut game = GameState::new(opts);
|
||||
pub fn simulate_once<'a>(
|
||||
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));
|
||||
|
||||
|
@ -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 {
|
||||
let mut total_score = 0;
|
||||
for _ in 0..n_trials {
|
||||
let score = simulate_once(&opts, strat_configs);
|
||||
for seed in 0..n_trials {
|
||||
let score = simulate_once(&opts, Some(seed), strat_configs);
|
||||
debug!("Scored: {:?}", score);
|
||||
if score != 25 {
|
||||
info!("Seed with non-perfect score: {:?}", seed);
|
||||
}
|
||||
total_score += score;
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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 {
|
||||
let mut strat_configs = Vec::new();
|
||||
for _ in 0..opts.num_players {
|
||||
|
|
Loading…
Reference in a new issue