summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorJustin Worthe <justin@worthe-it.co.za>2019-04-25 16:50:06 +0200
committerJustin Worthe <justin@worthe-it.co.za>2019-04-25 16:50:06 +0200
commit510767263a0060ad13b2488a9402b1d176ad65ef (patch)
tree8f5d1dc7bb290c01c54f30b4ebe2868d8ac80272 /tests
parent5c957c0c8e928cbe64eb8a84733d649fd32642ef (diff)
Test that match replay matches my simulation
Diffstat (limited to 'tests')
-rwxr-xr-xtests/import-replay.sh12
-rw-r--r--tests/official-runner-matching.rs142
-rwxr-xr-xtests/replays/import-replay.sh12
3 files changed, 146 insertions, 20 deletions
diff --git a/tests/import-replay.sh b/tests/import-replay.sh
new file mode 100755
index 0000000..51a7b83
--- /dev/null
+++ b/tests/import-replay.sh
@@ -0,0 +1,12 @@
+#/bin/sh
+
+# $1: The match-log directory
+# Should be run from the tests directory.
+
+logname=$(basename $1)
+
+mkdir $logname
+cp $1/A*.csv replays/$logname/A-log.csv
+cp $1/B*.csv replays/$logname/B-log.csv
+cp $1/Round\ 001/A*/JsonMap.json replays/$logname/A-init.json
+cp $1/Round\ 001/B*/JsonMap.json replays/$logname/B-init.json
diff --git a/tests/official-runner-matching.rs b/tests/official-runner-matching.rs
index 7ef12b8..12b6010 100644
--- a/tests/official-runner-matching.rs
+++ b/tests/official-runner-matching.rs
@@ -1,13 +1,139 @@
+use steam_powered_wyrm::json;
+use steam_powered_wyrm::game::*;
+use steam_powered_wyrm::command::Command;
+use std::path::Path;
+use std::fs::File;
+use std::io::prelude::*;
#[test]
fn simulates_the_same_match() {
- //TODO
- //iterate over list of replays (FS?)
-
- //read initial state.json
- //iterate over moves
- //simulate move (both sides)
- //assert state is as expected
- //repeat with players swapped?
+ let replays = Path::new("tests/replays/");
+ for replay in replays.read_dir().expect("read_dir failed") {
+ let replay = replay.expect("error on replay").path();
+
+ let mut game_board = GameBoard::new(
+ json::read_state_from_json_file(&replay.join(Path::new("A-init.json"))).expect("Failed to read initial state")
+ );
+ let player_csv = read_file_lines(&replay.join(Path::new("A-log.csv")), 1);
+ let opponent_csv = read_file_lines(&replay.join(Path::new("B-log.csv")), 1);
+
+ for round in 0..player_csv.len() {
+ println!("Testing round {}", round);
+
+ let player = split_csv(&player_csv[round]);
+ let opponent = split_csv(&opponent_csv[round]);
+
+ assert_eq!(round + 1, player[0].parse::<usize>().expect(&format!("Invalid player input on round {}", round)));
+ assert_eq!(round + 1, opponent[0].parse::<usize>().expect(&format!("Invalid opponent input on round {}", round)));
+
+ // active worm id field in CSV refers to the worm of the
+ // move. The rest of the state refers to after the move
+ // has happened.
+ assert_eq!(player[3].parse::<i32>().unwrap(), game_board.players[0].worms[game_board.players[0].active_worm].id, "Active worm is incorrect for player 0");
+ assert_eq!(opponent[3].parse::<i32>().unwrap(), game_board.players[1].worms[game_board.players[1].active_worm].id, "Active worm is incorrect for player 1");
+
+ if round != 0 {
+ let player_move = read_move(&player);
+ let opponent_move = read_move(&opponent);
+ let _ = game_board.simulate([player_move, opponent_move]);
+ }
+
+ for player_index in 0..2 {
+ let csv_row = match player_index {
+ 0 => &player,
+ _ => &opponent
+ };
+ for worm_index in 0..3 {
+ let worm_id = worm_index as i32 + 1;
+
+ match game_board.players[player_index].find_worm(worm_id) {
+ Some(worm) => {
+ assert_eq!(csv_row[6 + worm_index * 3].parse::<i32>().unwrap(), worm.health, "Worm health is incorrect for worm {} on player {}, Row: {:?}", worm_id, player_index, csv_row);
+ assert_eq!(csv_row[7 + worm_index * 3].parse::<i8>().unwrap(), worm.position.x, "Worm x is incorrect for worm {} on player {}, Row: {:?}", worm_id, player_index, csv_row);
+ assert_eq!(csv_row[8 + worm_index * 3].parse::<i8>().unwrap(), worm.position.y, "Worm y is incorrect for worm {} on player {}, Row: {:?}", worm_id, player_index, csv_row);
+ },
+ None => {
+ // If the worms don't appear in my state, they should be dead
+ assert!(csv_row[6 + worm_index * 3].parse::<i32>().unwrap() <= 0, "Worm is not actually dead");
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+fn read_file_lines(path: &Path, skip: usize) -> Vec<String> {
+ let mut file = File::open(path).unwrap();
+ let mut contents = String::new();
+ file.read_to_string(&mut contents).unwrap();
+ contents.split("\n").skip(skip).map(String::from).filter(|s| !s.is_empty()).collect()
+}
+
+fn split_csv(input: &str) -> Vec<String> {
+ let mut result = Vec::new();
+ let mut next = Vec::new();
+ let mut quoted = false;
+
+ for c in input.chars() {
+ match c {
+ '"' => {
+ quoted = !quoted;
+ },
+ ',' if !quoted => {
+ result.push(next.iter().collect());
+ next = Vec::new();
+ },
+ c => {
+ next.push(c);
+ }
+ }
+ }
+ result.push(next.iter().collect());
+ result
+}
+
+fn read_move(csv_line: &[String]) -> Command {
+ match csv_line[1].as_ref() {
+ "move" => {
+ let (x, y) = read_xy_pair(&csv_line[2]);
+ Command::Move(x, y)
+ },
+ "dig" => {
+ let (x, y) = read_xy_pair(&csv_line[2]);
+ Command::Dig(x, y)
+ },
+ "nothing" => {
+ Command::DoNothing
+ },
+ "shoot" => {
+ use steam_powered_wyrm::geometry::Direction::*;
+
+ let dir = match csv_line[2].as_ref() {
+ "shoot N" => North,
+ "shoot NE" => NorthEast,
+ "shoot E" => East,
+ "shoot SE" => SouthEast,
+ "shoot S" => South,
+ "shoot SW" => SouthWest,
+ "shoot W" => West,
+ "shoot NW" => NorthWest,
+ _ => panic!("Unknown shoot direction: {}", csv_line[2])
+ };
+ Command::Shoot(dir)
+ },
+ x => {
+ panic!("Unknown command {}", x);
+ }
+ }
+}
+
+fn read_xy_pair(input: &str) -> (i8, i8) {
+ let mut char_iter = input.chars();
+ let _ = char_iter.by_ref().take_while(|c| *c != '(').collect::<String>();
+ let x = char_iter.by_ref().take_while(|c| *c != ',').collect::<String>().trim().parse::<i8>().unwrap();
+ let y = char_iter.by_ref().take_while(|c| *c != ')').collect::<String>().trim().parse::<i8>().unwrap();
+ (x, y)
}
diff --git a/tests/replays/import-replay.sh b/tests/replays/import-replay.sh
deleted file mode 100755
index 034efed..0000000
--- a/tests/replays/import-replay.sh
+++ /dev/null
@@ -1,12 +0,0 @@
-#/bin/sh
-
-# $1: The match-log directory
-# Should be run from the target directory
-
-logname=$(basename $1)
-
-mkdir $logname
-cp $1/A*.csv $logname/A-log.csv
-cp $1/B*.csv $logname/B-log.csv
-cp $1/Round\ 001/A*/JsonMap.json $logname/A-init.json
-cp $1/Round\ 001/B*/JsonMap.json $logname/B-init.json