diff --git a/battle/src/battle.rs b/battle/src/battle.rs index 28c5693..8833ec5 100644 --- a/battle/src/battle.rs +++ b/battle/src/battle.rs @@ -18,7 +18,7 @@ pub struct Battle { impl Battle { pub fn new( - config: GameConfig, + p1_config: GameConfig, p2_config: GameConfig, p1_seed: ::Seed, p2_seed: ::Seed, garbage_seed: ::Seed @@ -26,18 +26,18 @@ impl Battle { let mut p1_rng = Pcg64Mcg::from_seed(p1_seed); let mut p2_rng = Pcg64Mcg::from_seed(p2_seed); let garbage_rng = Pcg64Mcg::from_seed(garbage_seed); - let player_1 = Game::new(config, &mut p1_rng); - let player_2 = Game::new(config, &mut p2_rng); + let player_1 = Game::new(p1_config, &mut p1_rng); + let player_2 = Game::new(p2_config, &mut p2_rng); Battle { replay: Replay { p1_name: String::new(), p2_name: String::new(), - config, p1_seed, p2_seed, garbage_seed, + p1_config, p2_config, p1_seed, p2_seed, garbage_seed, updates: VecDeque::new() }, player_1, player_2, p1_rng, p2_rng, garbage_rng, time: 0, - margin_time: config.margin_time, + margin_time: p1_config.margin_time, multiplier: 1.0, } } @@ -102,6 +102,7 @@ pub struct Replay { pub p1_seed: ::Seed, pub p2_seed: ::Seed, pub garbage_seed: ::Seed, - pub config: GameConfig, + pub p1_config: GameConfig, + pub p2_config: GameConfig, pub updates: VecDeque<(Controller, Controller)> } \ No newline at end of file diff --git a/battle/src/game.rs b/battle/src/game.rs index 206da51..3bb7bc7 100644 --- a/battle/src/game.rs +++ b/battle/src/game.rs @@ -122,6 +122,10 @@ impl Game { match self.state { GameState::SpawnDelay(0) => { + let mut events = vec![]; + if self.config.spawn_delay == 0 { + events.push(Event::FrameBeforePieceSpawns); + } let next_piece = self.board.advance_queue().unwrap(); let new_piece = self.board.generate_next_piece(piece_rng); self.board.add_next_piece(new_piece); @@ -136,14 +140,13 @@ impl Game { }); let mut ghost = spawned; ghost.sonic_drop(&self.board); - vec![ - Event::PieceSpawned { new_in_queue: new_piece }, - Event::PieceFalling(spawned, ghost) - ] + events.push(Event::PieceSpawned { new_in_queue: new_piece }); + events.push(Event::PieceFalling(spawned, ghost)); } else { self.state = GameState::GameOver; - vec![Event::GameOver] + events.push(Event::GameOver); } + events } GameState::SpawnDelay(ref mut delay) => { *delay -= 1; diff --git a/compare/src/input.rs b/compare/src/input.rs index 9be1fb1..2917680 100644 --- a/compare/src/input.rs +++ b/compare/src/input.rs @@ -10,7 +10,7 @@ pub struct BotInput { bot: bot::BotState } -const THINK_AMOUNT: Duration = Duration::from_millis(2); +const THINK_AMOUNT: Duration = Duration::from_millis(4); impl BotInput { pub fn new(board: Board, eval: E) -> Self { diff --git a/compare/src/main.rs b/compare/src/main.rs index b37d068..4df2931 100644 --- a/compare/src/main.rs +++ b/compare/src/main.rs @@ -18,7 +18,7 @@ fn main() { let (send, recv) = std::sync::mpsc::channel(); - for _ in 0..2 { + for _ in 0..12 { let p1_eval = p1_eval.clone(); let p2_eval = p2_eval.clone(); let send = send.clone(); @@ -32,7 +32,7 @@ fn main() { let mut p1_wins = 0; let mut p2_wins = 0; - let games = 3000; + let games = 5000; while p1_wins + p2_wins < games { match recv.recv() { @@ -59,7 +59,8 @@ fn main() { fn do_battle(p1: impl Evaluator, p2: impl Evaluator) -> (InfoReplay, bool) { let mut battle = Battle::new( - Default::default(), thread_rng().gen(), thread_rng().gen(), thread_rng().gen() + Default::default(), Default::default(), + thread_rng().gen(), thread_rng().gen(), thread_rng().gen() ); battle.replay.p1_name = format!("Cold Clear\n{}", p1.name()); diff --git a/gui/src/local.rs b/gui/src/local.rs index 6cab0ce..f94c806 100644 --- a/gui/src/local.rs +++ b/gui/src/local.rs @@ -28,7 +28,8 @@ pub struct LocalGame<'a> { p2_info_updates: VecDeque>, state: State, resources: &'a mut Resources, - config: GameConfig, + p1_config: GameConfig, + p2_config: GameConfig, gamepad: Option } @@ -43,10 +44,10 @@ impl<'a> LocalGame<'a> { resources: &'a mut Resources, p1: Box, p2: Box, - config: GameConfig + p1_config: GameConfig, p2_config: GameConfig ) -> Self { let mut battle = Battle::new( - config, thread_rng().gen(), thread_rng().gen(), thread_rng().gen() + p1_config, p2_config, thread_rng().gen(), thread_rng().gen(), thread_rng().gen() ); let (p1_input, p1_name) = p1(battle.player_1.board.to_compressed()); let (p2_input, p2_name) = p2(battle.player_2.board.to_compressed()); @@ -64,7 +65,7 @@ impl<'a> LocalGame<'a> { p2_info_updates: VecDeque::new(), state: State::Starting(180), resources, - config, + p1_config, p2_config, gamepad: None } } @@ -92,7 +93,7 @@ impl EventHandler for LocalGame<'_> { while timer::check_update_time(ctx, 60) {} self.battle = Battle::new( - self.config, + self.p1_config, self.p2_config, thread_rng().gen(), thread_rng().gen(), thread_rng().gen() ); diff --git a/gui/src/main.rs b/gui/src/main.rs index 999fe47..a2168dd 100644 --- a/gui/src/main.rs +++ b/gui/src/main.rs @@ -106,7 +106,7 @@ fn main() { use bot::evaluation::{ self, Evaluator }; use crate::input::BotInput; let Options { - controls, bot_options, bot_config, config + controls, bot_options, bot_config, p1_config, p2_config } = match read_options() { Ok(options) => options, Err(e) => { @@ -138,7 +138,7 @@ fn main() { bot_config.clone() ))), name) }), - config + p1_config, p2_config ); event::run(&mut ctx, &mut events, &mut local_game).unwrap(); } @@ -163,7 +163,8 @@ fn read_options() -> Result> { #[derive(Serialize, Deserialize, Clone, Debug, Default)] struct Options { controls: UserInput, - config: GameConfig, + p1_config: GameConfig, + p2_config: GameConfig, bot_config: bot::evaluation::Standard, bot_options: bot::Options } \ No newline at end of file diff --git a/gui/src/replay.rs b/gui/src/replay.rs index b764af2..b4961ea 100644 --- a/gui/src/replay.rs +++ b/gui/src/replay.rs @@ -28,7 +28,9 @@ impl<'a, P: AsRef + Clone> ReplayGame<'a, P> { deflate::Decoder::new(std::fs::File::open(file.clone()).unwrap()) ).unwrap(); let battle = Battle::new( - replay.config, replay.p1_seed, replay.p2_seed, replay.garbage_seed + replay.p1_config, replay.p2_config, + replay.p1_seed, replay.p2_seed, + replay.garbage_seed ); ReplayGame { gui: Gui::new(&battle, replay.p1_name, replay.p2_name), @@ -75,7 +77,9 @@ impl + Clone> EventHandler for ReplayGame<'_, P> { } let InfoReplay { replay, p1_info_updates, p2_info_updates } = replay; let battle = Battle::new( - replay.config, replay.p1_seed, replay.p2_seed, replay.garbage_seed + replay.p1_config, replay.p2_config, + replay.p1_seed, replay.p2_seed, + replay.garbage_seed ); self.gui = Gui::new(&battle, replay.p1_name, replay.p2_name); self.battle = battle; diff --git a/optimizer/src/battle.rs b/optimizer/src/battle.rs index 4e75e66..7763159 100644 --- a/optimizer/src/battle.rs +++ b/optimizer/src/battle.rs @@ -75,7 +75,8 @@ impl BotInput { pub fn do_battle(p1: impl Evaluator, p2: impl Evaluator) -> Option<(InfoReplay, bool)> { let mut battle = Battle::new( - Default::default(), thread_rng().gen(), thread_rng().gen(), thread_rng().gen() + Default::default(), Default::default(), + thread_rng().gen(), thread_rng().gen(), thread_rng().gen() ); battle.replay.p1_name = format!("Cold Clear\n{}", p1.name());