summaryrefslogtreecommitdiff
path: root/tests/official-runner-matching.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/official-runner-matching.rs')
-rw-r--r--tests/official-runner-matching.rs172
1 files changed, 130 insertions, 42 deletions
diff --git a/tests/official-runner-matching.rs b/tests/official-runner-matching.rs
index 8a0320f..fcc648f 100644
--- a/tests/official-runner-matching.rs
+++ b/tests/official-runner-matching.rs
@@ -1,11 +1,11 @@
-use steam_powered_wyrm::json;
+use steam_powered_wyrm::command::{Action, Command};
use steam_powered_wyrm::game::*;
-use steam_powered_wyrm::command::{Command, Action};
use steam_powered_wyrm::geometry::*;
+use steam_powered_wyrm::json;
-use std::path::Path;
use std::fs::File;
use std::io::prelude::*;
+use std::path::Path;
#[test]
fn simulates_the_same_match() {
@@ -14,50 +14,97 @@ fn simulates_the_same_match() {
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")
+ 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)));
+ 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 player_move = read_move(
+ &player,
+ game_board.players[0].worms[game_board.players[0].active_worm].id,
+ );
+ let opponent_move = read_move(
+ &opponent,
+ game_board.players[1].worms[game_board.players[1].active_worm].id,
+ );
let _ = game_board.simulate([player_move, opponent_move]);
+ if player[1] == "invalid" {
+ game_board.players[0].moves_score -= 4;
+ }
+ if opponent[1] == "invalid" {
+ game_board.players[1].moves_score -= 4;
+ }
}
for player_index in 0..2 {
let csv_row = match player_index {
0 => &player,
- _ => &opponent
+ _ => &opponent,
};
- assert_eq!(csv_row[4].parse::<i32>().unwrap(), game_board.players[player_index].score(), "Score is incorrect for player {}, Row: {:?}", player_index, csv_row);
+ assert_eq!(
+ csv_row[4].parse::<i32>().unwrap(),
+ game_board.players[player_index].score(),
+ "Score is incorrect for player {}, Row: {:?}",
+ player_index,
+ csv_row
+ );
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);
- },
+ 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");
+ assert!(
+ csv_row[6 + worm_index * 3].parse::<i32>().unwrap() <= 0,
+ "Worm is not actually dead"
+ );
}
}
}
@@ -66,28 +113,32 @@ fn simulates_the_same_match() {
}
}
-
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()
+ 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);
}
@@ -97,22 +148,42 @@ fn split_csv(input: &str) -> Vec<String> {
result
}
-fn read_move(csv_line: &[String]) -> Command {
+fn read_move(csv_line: &[String], expected_worm_id: i32) -> Command {
+ let worm_id = csv_line[3].parse::<i32>().unwrap();
+ let select = if worm_id == expected_worm_id {
+ None
+ } else {
+ Some(worm_id)
+ };
match csv_line[1].as_ref() {
"move" => {
let (x, y) = read_xy_pair(&csv_line[2]);
- Command::new(Action::Move(Point2d::new(x, y)))
- },
+ Command {
+ worm: select,
+ action: Action::Move(Point2d::new(x, y)),
+ }
+ }
"dig" => {
let (x, y) = read_xy_pair(&csv_line[2]);
- Command::new(Action::Dig(Point2d::new(x, y)))
- },
- "nothing" => {
- Command::new(Action::DoNothing)
+ Command {
+ worm: select,
+ action: Action::Dig(Point2d::new(x, y)),
+ }
+ }
+ "banana" => {
+ let (x, y) = read_xy_pair(&csv_line[2]);
+ Command {
+ worm: select,
+ action: Action::Bomb(Point2d::new(x, y)),
+ }
+ }
+ "nothing" | "invalid" => Command {
+ worm: select,
+ action: Action::DoNothing,
},
"shoot" => {
use steam_powered_wyrm::geometry::Direction::*;
-
+
let dir = match csv_line[2].as_ref() {
"shoot N" => North,
"shoot NE" => NorthEast,
@@ -122,11 +193,13 @@ fn read_move(csv_line: &[String]) -> Command {
"shoot SW" => SouthWest,
"shoot W" => West,
"shoot NW" => NorthWest,
- _ => panic!("Unknown shoot direction: {}", csv_line[2])
+ _ => panic!("Unknown shoot direction: {}", csv_line[2]),
};
- Command::new(Action::Shoot(dir))
- },
- // TODO: Parsing of new commands
+ Command {
+ worm: select,
+ action: Action::Shoot(dir),
+ }
+ }
x => {
panic!("Unknown command {}", x);
}
@@ -135,8 +208,23 @@ fn read_move(csv_line: &[String]) -> Command {
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();
+ 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)
}