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::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 {
|
||||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -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
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue