From f8a0e0f7f2f9cd5fb69899b5d7037bc969df4339 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Tue, 19 Apr 2022 21:36:41 +0200 Subject: Refile for merging repos --- 2020-overdrive/tests/live_comparison.rs | 134 ++++++++++++++++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 2020-overdrive/tests/live_comparison.rs (limited to '2020-overdrive/tests/live_comparison.rs') diff --git a/2020-overdrive/tests/live_comparison.rs b/2020-overdrive/tests/live_comparison.rs new file mode 100644 index 0000000..3e29069 --- /dev/null +++ b/2020-overdrive/tests/live_comparison.rs @@ -0,0 +1,134 @@ +extern crate vroomba; + +use vroomba::command::Command; +use vroomba::json; +use vroomba::state::{GameState, GameStateUpdateEvents}; + +use std::fs::File; +use std::io::prelude::*; +use std::path::Path; + +#[test] +fn it_successfully_simulates_replay() { + test_from_replay(&Path::new("tests/v1-normal-match/")); +} + +fn test_from_replay(replay_folder: &Path) { + let length = replay_folder.read_dir().unwrap().count() - 1; + + let mut state = json::read_state_from_json_file(&format!( + "{}/Round 001/JsonMap.json", + replay_folder.display() + )) + .unwrap(); + + println!("State 1: {:?}", state); + + for i in 1..=length { + let player = read_player_command(&format!( + "{}/Round {:03}/PlayerCommand.txt", + replay_folder.display(), + i + )); + let opponent = read_player_command(&format!( + "{}/Round {:03}/OpponentCommand.txt", + replay_folder.display(), + i + )); + let expected_state = json::read_state_from_json_file(&format!( + "{}/Round {:03}/JsonMap.json", + replay_folder.display(), + i + 1 + )) + .unwrap(); + + // We don't know how many they actually have from the state + // files. + state.players[1].boosts = 1; + state.players[1].oils = 1; + + println!("Player 1: {}, Player 2: {}", player, opponent); + state.update([player, opponent], &mut GameStateUpdateEvents::default()); + + println!("State {}: {:?}", i + 1, state); + assert_eq!( + state.status, + expected_state.status, + "\nFailed on state {}\n", + i + 1 + ); + player_assertions(&state, &expected_state, 0, true, i + 1); + + // TODO: We're only reading the state for player 1, so we can't say what obstacles player 2 may be hitting. Maybe read the full map of obstacles + powerups into the game state at the beginning? There's also the case of boost_remaining ofr player 2. + // player_assertions(&state, &expected_state, 1, false, i + 1); + + // We can do great simulations into the future, but we need to + // be told where the future mud is. + state = expected_state; + } +} + +fn read_player_command(filename: &str) -> Command { + let mut file = File::open(filename).unwrap(); + let mut content = String::new(); + file.read_to_string(&mut content).unwrap(); + match content.trim() { + "Command: ACCELERATE" => Command::Accelerate, + "Command: NOTHING" => Command::Nothing, + "Command: DECELERATE" => Command::Decelerate, + "Command: TURN_LEFT" => Command::TurnLeft, + "Command: TURN_RIGHT" => Command::TurnRight, + "Command: USE_BOOST" => Command::UseBoost, + "Command: USE_OIL" => Command::UseOil, + other => panic!("Unexpected command: {}", other), + } +} + +fn player_assertions( + actual: &GameState, + expected: &GameState, + player_index: usize, + compare_powerups: bool, + round: usize, +) { + let actual = &actual.players[player_index]; + let expected = &expected.players[player_index]; + + assert_eq!( + actual.position, + expected.position, + "\nFailed on state {}, player {} position\n", + round, + player_index + 1 + ); + assert_eq!( + actual.speed, + expected.speed, + "\nFailed on state {}, player {} speed\n", + round, + player_index + 1 + ); + if compare_powerups { + assert_eq!( + actual.boost_remaining, + expected.boost_remaining, + "\nFailed on state {}, player {} position,\n", + round, + player_index + 1 + ); + assert_eq!( + actual.oils, + expected.oils, + "\nFailed on state {}, player {} oils,\n", + round, + player_index + 1 + ); + assert_eq!( + actual.boosts, + expected.boosts, + "\nFailed on state {}, player {} boosts,\n", + round, + player_index + 1 + ); + } +} -- cgit v1.2.3