#![cfg(test)]
use std::{fmt, str::FromStr, time::Duration};
use crate::{
ai::{AI, AiBanal},
board::BoardSize,
game_tree::Tree,
};
use super::*;
use board::{Board, STARTING_POSITION_11X11};
use game::Game;
use play::Vertex;
use role::Role;
use status::Status;
fn assert_error_str<T: fmt::Debug>(result: anyhow::Result<T>, string: &str) {
if let Err(error) = result {
assert_eq!(error.to_string(), string);
}
}
#[test]
fn monte_carlo() {
let mut tree = Tree::new(Game::new_game(BoardSize::_11, None));
let depth = 80;
let (loops, _plays) = tree.monte_carlo_tree_search(Duration::from_secs(1), depth);
println!("{loops}");
}
#[ignore = "takes too long"]
#[test]
fn monte_carlo_long() {
let mut tree = Tree::new(Game::new_game(BoardSize::_11, None));
let depth = 40;
let (loops, _plays) = tree.monte_carlo_tree_search(Duration::from_secs(10), depth);
println!("{loops}");
}
#[test]
fn flood_fill_1() -> anyhow::Result<()> {
let board_1 = [
"...........",
".........X.",
"...........",
"...........",
"...........",
"...........",
"...........",
".....O.....",
"....O.O....",
"....O.O....",
"....OKO....",
];
let game = game::Game {
board: board_1.try_into()?,
turn: Role::Defender,
..Default::default()
};
let vertex = Vertex::from_str("f1")?;
assert!(game.board.flood_fill_defender_wins(&vertex));
Ok(())
}
#[test]
fn flood_fill_2() -> anyhow::Result<()> {
let board_1 = [
"...........",
".........X.",
"...........",
"...........",
"...........",
"...........",
"...........",
"....OO.....",
"....O......",
"....O.O....",
"....OKO....",
];
let game = game::Game {
board: board_1.try_into()?,
turn: Role::Defender,
..Default::default()
};
let vertex = Vertex::from_str("f1")?;
assert!(!game.board.flood_fill_defender_wins(&vertex));
Ok(())
}
#[test]
fn starting_position() -> anyhow::Result<()> {
let game = Game::default();
assert_eq!(game.board, STARTING_POSITION_11X11.try_into()?);
Ok(())
}
#[test]
fn first_turn() {
let game = Game::default();
assert_eq!(game.turn, Role::Attacker);
}
#[test]
fn move_orthogonally_1() -> anyhow::Result<()> {
let board = [
"...X.......",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"X..O......X",
"...........",
"...........",
"...X.......",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
let mut result = game.read_line("play defender d4 d1");
assert!(result.is_err());
assert_error_str(result, "play: you have to play through empty locations");
result = game.read_line("play defender d4 d11");
assert!(result.is_err());
assert_error_str(result, "play: you have to play through empty locations");
result = game.read_line("play defender d4 a4");
assert!(result.is_err());
assert_error_str(result, "play: you have to play through empty locations");
result = game.read_line("play defender d4 k4");
assert!(result.is_err());
assert_error_str(result, "play: you have to play through empty locations");
Ok(())
}
#[test]
fn move_orthogonally_2() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...O.......",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
let mut result = game.read_line("play defender junk d1");
assert!(result.is_err());
assert_error_str(result, "invalid digit found in string");
result = game.read_line("play defender d4 junk");
assert!(result.is_err());
assert_error_str(result, "invalid digit found in string");
result = game.read_line("play defender d4 a3");
assert!(result.is_err());
assert_error_str(result, "play: you can only play in a straight line");
result = game.read_line("play defender d4 m4");
assert!(result.is_err());
assert_error_str(result, "play: the first letter is not a legal char");
result = game.read_line("play defender d4 d12");
assert!(result.is_err());
assert_error_str(result, "play: invalid coordinate");
result = game.read_line("play defender d4 d0");
assert!(result.is_err());
assert_error_str(result, "play: invalid coordinate");
result = game.read_line("play defender d4 d4");
assert!(result.is_err());
assert_error_str(result, "play: you have to change location");
let mut game_1 = game.clone();
game_1.read_line("play defender d4 a4")?;
let mut game_2 = game.clone();
game_2.read_line("play defender d4 k4")?;
let mut game_3 = game.clone();
game_3.read_line("play defender d4 d11")?;
let mut game_4 = game.clone();
game_4.read_line("play defender d4 d1")?;
Ok(())
}
#[test]
fn sandwich_capture_1() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...X.......",
"...O.......",
".XO.OX.....",
"...........",
"...X.......",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...X.......",
"...........",
".X.X.X.....",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game.read_line("play attacker d2 d4")?;
assert_eq!(game.board, board_2.try_into()?);
Ok(())
}
#[test]
fn sandwich_capture_2() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...X.......",
"...K.......",
".XO.OX.....",
"...........",
"...X.......",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...X.......",
"...K.......",
".X.X.X.....",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game.read_line("play attacker d2 d4")?;
assert_eq!(game.board, board_2.try_into()?);
Ok(())
}
#[test]
fn sandwich_capture_3() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".....O.....",
".X.........",
"...........",
"...........",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".....X.....",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game.read_line("play attacker b4 f4")?;
assert_eq!(game.board, board_2.try_into()?);
Ok(())
}
#[test]
fn sandwich_capture_4() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"..K........",
"...........",
"...........",
"..X........",
"..O........",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"..K........",
"...........",
"..O........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender c6 c4")?;
assert_eq!(game.board, board_2.try_into()?);
Ok(())
}
#[test]
fn sandwich_capture_5() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
".....X.....",
".O.........",
"...........",
"...........",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
"...........",
".....O.....",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender b4 f4")?;
assert_eq!(game.board, board_2.try_into()?);
Ok(())
}
#[test]
fn sandwich_capture_6() -> anyhow::Result<()> {
let board_1 = [
".O.........",
"...........",
"..X........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let board_2 = [
"..X........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game.read_line("play attacker c9 c11")?;
assert_eq!(game.board, board_2.try_into()?);
Ok(())
}
#[test]
fn sandwich_capture_7() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
".....O.....",
".X.........",
"...........",
"...........",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
".....O.....",
".....X.....",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game.read_line("play attacker b4 f4")?;
assert_eq!(game.board, board_2.try_into()?);
Ok(())
}
#[test]
fn sandwich_capture_8() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".O.O.......",
"...........",
"..X........",
"...........",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".OXO.......",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game.read_line("play attacker c3 c5")?;
assert_eq!(game.board, board_2.try_into()?);
Ok(())
}
#[test]
fn shield_wall_1() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"..O........",
"...OOO.....",
"...XXXO....",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...OOO.....",
"..O...O....",
];
let mut game_1 = game::Game {
board: board_1.try_into()?,
turn: Role::Defender,
..Default::default()
};
game_1.read_line("play defender c3 c1")?;
assert_eq!(game_1.board, board_2.try_into()?);
let board_3 = [
"...XXXO....",
"...OOO.....",
"..O........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let board_4 = [
"..O...O....",
"...OOO.....",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game_2 = game::Game {
board: board_3.try_into()?,
turn: Role::Defender,
..Default::default()
};
game_2.read_line("play defender c9 c11")?;
assert_eq!(game_2.board, board_4.try_into()?);
Ok(())
}
#[test]
fn shield_wall_1_13() -> anyhow::Result<()> {
let board_1 = [
"...XXXO......",
"...OOO.......",
"..O..........",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
];
let board_2 = [
"..O...O......",
"...OOO.......",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
];
let mut game_1 = game::Game {
board: board_1.try_into()?,
turn: Role::Defender,
..Default::default()
};
game_1.read_line("play defender C11 C13")?;
assert_eq!(game_1.board, board_2.try_into()?);
Ok(())
}
#[test]
fn shield_wall_2() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"..O........",
"XO.........",
"XO.........",
"XO.........",
"O..........",
"...........",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"O..........",
".O.........",
".O.........",
".O.........",
"O..........",
"...........",
"...........",
];
let mut game_1 = game::Game {
board: board_1.try_into()?,
turn: Role::Defender,
..Default::default()
};
game_1.read_line("play defender c7 a7")?;
assert_eq!(game_1.board, board_2.try_into()?);
let board_3 = [
"...........",
"...........",
"...........",
"...........",
"........O..",
".........OX",
".........OX",
".........OX",
"..........O",
"...........",
"...........",
];
let board_4 = [
"...........",
"...........",
"...........",
"...........",
"..........O",
".........O.",
".........O.",
".........O.",
"..........O",
"...........",
"...........",
];
let mut game_2 = game::Game {
board: board_3.try_into()?,
turn: Role::Defender,
..Default::default()
};
game_2.read_line("play defender i7 k7")?;
assert_eq!(game_2.board, board_4.try_into()?);
Ok(())
}
#[test]
fn shield_wall_3() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"........XX.",
".....X..OK.",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"........XX.",
".......X.K.",
];
let mut game_1 = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game_1.read_line("play attacker f1 h1")?;
assert_eq!(game_1.board, board_2.try_into()?);
let board_3 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".XX........",
".KO..X.....",
];
let board_4 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".XX........",
".K.X.......",
];
let mut game_2 = game::Game {
board: board_3.try_into()?,
..Default::default()
};
game_2.read_line("play attacker f1 d1")?;
assert_eq!(game_2.board, board_4.try_into()?);
Ok(())
}
#[test]
fn shield_wall_4() -> anyhow::Result<()> {
let board_1 = [
".....X..OK.",
"........XX.",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let board_2 = [
".......X.K.",
"........XX.",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game_1 = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game_1.read_line("play attacker f11 h11")?;
assert_eq!(game_1.board, board_2.try_into()?);
let board_3 = [
".KO..X.....",
".XX........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let board_4 = [
".K.X.......",
".XX........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game_2 = game::Game {
board: board_3.try_into()?,
..Default::default()
};
game_2.read_line("play attacker f11 d11")?;
assert_eq!(game_2.board, board_4.try_into()?);
Ok(())
}
#[test]
fn shield_wall_5() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"X..........",
"...........",
"...........",
"OX.........",
"KX.........",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"X..........",
".X.........",
"KX.........",
"...........",
];
let mut game_1 = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game_1.read_line("play attacker a6 a4")?;
assert_eq!(game_1.board, board_2.try_into()?);
let board_3 = [
"...........",
"KX.........",
"OX.........",
"...........",
"...........",
"X..........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let board_4 = [
"...........",
"KX.........",
".X.........",
"X..........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game_2 = game::Game {
board: board_3.try_into()?,
..Default::default()
};
game_2.read_line("play attacker a6 a8")?;
assert_eq!(game_2.board, board_4.try_into()?);
Ok(())
}
#[test]
fn shield_wall_6() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"..........X",
"...........",
"...........",
".........XO",
".........XK",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"..........X",
".........X.",
".........XK",
"...........",
];
let mut game_1 = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game_1.read_line("play attacker k6 k4")?;
assert_eq!(game_1.board, board_2.try_into()?);
let board_3 = [
"...........",
".........XK",
".........XO",
"...........",
"...........",
"..........X",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let board_4 = [
"...........",
".........XK",
".........X.",
"..........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game_2 = game::Game {
board: board_3.try_into()?,
..Default::default()
};
game_2.read_line("play attacker k6 k8")?;
assert_eq!(game_2.board, board_4.try_into()?);
Ok(())
}
#[test]
fn shield_wall_7() -> anyhow::Result<()> {
let board_1 = [
"...........",
"........X.O",
"..........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let board_2 = [
"...........",
".........XO",
"..........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game.read_line("play attacker i10 j10")?;
assert_eq!(game.board, board_2.try_into()?);
let board_3 = [
"...........",
"..........X",
"........X.O",
"..........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let board_4 = [
"...........",
"..........X",
".........XO",
"..........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_3.try_into()?,
..Default::default()
};
game.read_line("play attacker i9 j9")?;
assert_eq!(game.board, board_4.try_into()?);
Ok(())
}
#[test]
fn shield_wall_nope() -> anyhow::Result<()> {
let board_1 = [
"...........",
"........X.O",
".........XO",
"..........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let board_2 = [
"...........",
".........XO",
".........XO",
"..........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game.read_line("play attacker i10 j10")?;
assert_eq!(game.board, board_2.try_into()?);
Ok(())
}
#[test]
fn kings_1() {
let board = [
"KK.........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let result: anyhow::Result<Board> = board.try_into();
assert!(result.is_err());
assert_error_str(result, "You can only have one king!");
}
#[test]
fn kings_2() -> anyhow::Result<()> {
let board = [
".X.........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
let result = game.read_line("play attacker b11 a11");
assert!(result.is_err());
assert_error_str(
result,
"play: only the king may move to a restricted square",
);
Ok(())
}
#[test]
fn kings_3() -> anyhow::Result<()> {
let board_1 = [
"K..........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let _board: Board = board_1.try_into()?;
let board_2 = [
"X..........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let result: anyhow::Result<Board> = board_2.try_into();
assert!(result.is_err());
assert_error_str(result, "Only the king is allowed on restricted squares!");
Ok(())
}
#[test]
fn kings_4() -> anyhow::Result<()> {
let board_1 = [
"..........K",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let _board: Board = board_1.try_into()?;
let board_2 = [
"..........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let result: anyhow::Result<Board> = board_2.try_into();
assert!(result.is_err());
assert_error_str(result, "Only the king is allowed on restricted squares!");
Ok(())
}
#[test]
fn kings_5() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let _board: Board = board_1.try_into()?;
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
".....X.....",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let result: anyhow::Result<Board> = board_2.try_into();
assert!(result.is_err());
assert_error_str(result, "Only the king is allowed on restricted squares!");
Ok(())
}
#[test]
fn kings_6() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"K..........",
];
let _board: Board = board_1.try_into()?;
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"X..........",
];
let result: anyhow::Result<Board> = board_2.try_into();
assert!(result.is_err());
assert_error_str(result, "Only the king is allowed on restricted squares!");
Ok(())
}
#[test]
fn kings_7() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"..........K",
];
let _board: Board = board_1.try_into()?;
let board_2 = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"..........X",
];
let result: anyhow::Result<Board> = board_2.try_into();
assert!(result.is_err());
assert_error_str(result, "Only the king is allowed on restricted squares!");
Ok(())
}
#[test]
fn defender_wins_exit() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
];
let mut game_1 = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
let mut game_2 = game_1.clone();
game_1.read_line("play defender f1 k1")?;
assert_eq!(game_1.status, Status::DefenderWins);
game_2.read_line("play defender f1 a1")?;
assert_eq!(game_2.status, Status::DefenderWins);
let board = [
".....K.....",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game_1 = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
let mut game_2 = game_1.clone();
game_1.read_line("play defender f11 k11")?;
assert_eq!(game_1.status, Status::DefenderWins);
game_2.read_line("play defender f11 a11")?;
assert_eq!(game_2.status, Status::DefenderWins);
Ok(())
}
#[test]
fn defender_wins_escape_fort_1() -> anyhow::Result<()> {
let board = [
"....O.O....",
"....OKO....",
"....OO.....",
"....XX.....",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender f10 f11")?;
assert_eq!(game.status, Status::DefenderWins);
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"....XX.....",
"....OO.....",
"....OKO....",
"....O.O....",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender f2 f1")?;
assert_eq!(game.status, Status::DefenderWins);
let board = [
"...........",
"...........",
"...........",
"...........",
"OOOX.......",
".KOX.......",
"OO.........",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender b6 a6")?;
assert_eq!(game.status, Status::DefenderWins);
let board = [
"...........",
"...........",
"...........",
"...........",
".......XOOO",
".......XOK.",
".........OO",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender j6 k6")?;
assert_eq!(game.status, Status::DefenderWins);
Ok(())
}
#[test]
fn defender_wins_escape_fort_1_13() -> anyhow::Result<()> {
let board = [
"....OKO......",
"....O........",
"....OOO......",
"....XX.......",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
".............",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender G11 G12")?;
assert_eq!(game.status, Status::DefenderWins);
Ok(())
}
#[test]
fn defender_wins_escape_fort_2() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"........XOO",
"........OK.",
".......X.OO",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender j6 k6")?;
assert_eq!(game.status, Status::Ongoing);
let board = [
"...........",
"...........",
"...........",
"...........",
"........XOO",
"........OK.",
".........OO",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender j6 k6")?;
assert_eq!(game.status, Status::DefenderWins);
Ok(())
}
#[test]
fn defender_wins_escape_fort_3() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"........X.O",
".........O.",
".......X.OK",
"..........O",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender k5 k6")?;
assert_eq!(game.status, Status::DefenderWins);
Ok(())
}
#[test]
fn kings_not_captured() -> anyhow::Result<()> {
let board_1 = [
"...........",
"...........",
"...........",
".....X.....",
"...........",
".....KX....",
".....X.....",
"...........",
"...........",
"...........",
"...........",
];
let board_2 = [
"...........",
"...........",
"...........",
"...........",
".....X.....",
".....KX....",
".....X.....",
"...........",
"...........",
"...........",
"...........",
]
.try_into()?;
let mut game = game::Game {
board: board_1.try_into()?,
..Default::default()
};
game.read_line("play attacker f8 f7")?;
assert_eq!(game.board, board_2);
Ok(())
}
#[test]
fn kings_captured_1() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
".....X.....",
"...........",
"....XKX....",
".....X.....",
"...........",
"...........",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
game.read_line("play attacker f8 f7")?;
assert_eq!(game.status, Status::AttackerWins);
Ok(())
}
#[test]
fn kings_captured_2() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"....XKX....",
"...........",
".....X.....",
"...........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
game.read_line("play attacker f3 f4")?;
assert_eq!(game.status, Status::AttackerWins);
Ok(())
}
#[test]
fn kings_captured_3() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"....X......",
"...XKX.....",
"...........",
"....X......",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
game.read_line("play attacker e1 e2")?;
assert_eq!(game.status, Status::AttackerWins);
Ok(())
}
#[test]
fn kings_captured_4() -> anyhow::Result<()> {
let board = [
"...........",
".O.........",
"...........",
"...........",
"...........",
"...........",
"...........",
"X..........",
"K.X........",
"X..........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
game.read_line("play attacker c3 b3")?;
assert_eq!(game.status, Status::Ongoing);
Ok(())
}
#[test]
fn kings_captured_5() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"X..........",
"K.X........",
"...........",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
game.read_line("play attacker c2 b2")?;
assert_eq!(game.status, Status::Ongoing);
Ok(())
}
#[test]
fn kings_captured_surround_1() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
".....XXX...",
"....X...XX.",
".X...O....X",
"..X.......X",
".X.O...O..X",
".X..OK...X.",
"..X...O.X..",
"...XXX.X...",
"......X....",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
game.read_line("play attacker b7 c7")?;
assert_eq!(game.status, Status::Ongoing);
game.read_line("play defender f7 g7")?;
assert_eq!(game.status, Status::Ongoing);
game.read_line("play attacker c7 d7")?;
assert_eq!(game.status, Status::AttackerWins);
Ok(())
}
#[test]
fn kings_captured_surround_2() -> anyhow::Result<()> {
let board = [
"...........",
"...O.......",
".....XXX...",
"....X...XX.",
"..X..O....X",
"..X.......X",
".X.O...O..X",
".X..OK...X.",
"..X...O.X..",
"...XXX.X...",
"......X....",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
game.read_line("play attacker c7 d7")?;
assert_eq!(game.status, Status::Ongoing);
Ok(())
}
#[test]
fn can_not_repeat_moves() -> anyhow::Result<()> {
let mut game = Game::default();
game.read_line("play attacker f2 f3")?;
game.read_line("play defender f4 g4")?;
game.read_line("play attacker f3 f2")?;
let result = game.read_line("play defender g4 f4");
assert!(result.is_err());
assert_error_str(result, "play: you already reached that position");
Ok(())
}
#[test]
fn attacker_automatically_loses() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
".....X.....",
"...........",
".....O.....",
];
let mut game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
game.read_line("play defender f1 f2")?;
assert_eq!(game.status, Status::DefenderWins);
Ok(())
}
#[test]
fn defender_automatically_loses_1() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".....X.....",
".X..XKX....",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
game.read_line("play attacker b1 b2")?;
assert_eq!(game.status, Status::AttackerWins);
Ok(())
}
#[test]
fn defender_automatically_loses_2() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".....X.....",
".X..X.X....",
"....XKX....",
];
let mut game = game::Game {
board: board.try_into()?,
..Default::default()
};
game.read_line("play attacker b2 b1")?;
game.read_line("play defender f1 f2")?;
game.read_line("play attacker b1 b2")?;
game.read_line("play defender f2 f1")?;
game.read_line("play attacker b2 b1")?;
assert_eq!(game.status, Status::AttackerWins);
Ok(())
}
#[test]
fn exit_one_1() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".X...K...X.",
];
let game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
assert!(!game.exit_one());
Ok(())
}
#[test]
fn exit_one_2() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
];
let game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
assert!(game.exit_one());
Ok(())
}
#[test]
fn exit_one_3() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
"...........",
];
let game = game::Game {
board: board.try_into()?,
turn: Role::Defender,
..Default::default()
};
assert!(!game.exit_one());
Ok(())
}
#[test]
fn exit_one_4() -> anyhow::Result<()> {
let board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
".....K.....",
];
let game = game::Game {
board: board.try_into()?,
..Default::default()
};
assert!(!game.exit_one());
Ok(())
}
#[test]
fn closed_off_exits() -> anyhow::Result<()> {
let board: Board = [
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"X..........",
".X.........",
"..X..K.....",
]
.try_into()?;
assert_eq!(board.closed_off_exits(), 1);
let board: Board = [
"..X....X...",
".X......X..",
"X........X.",
"X.........X",
"X..........",
"X..........",
"X..........",
"X..........",
"X.........X",
".X.......X.",
"..X..K..X..",
]
.try_into()?;
assert_eq!(board.closed_off_exits(), 4);
let board: Board = [
".XX.....XX.",
"X.........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"...........",
"X.........X",
".XX..K..XX.",
]
.try_into()?;
assert_eq!(board.closed_off_exits(), 0);
let board: Board = [
".X.......X.",
"X.........X",
"X.........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"X.........X",
"X.........X",
".X...K...X.",
]
.try_into()?;
assert_eq!(board.closed_off_exits(), 0);
let board: Board = [
".XX.....XX.",
"X.........X",
"X.........X",
"...........",
"...........",
"...........",
"...........",
"...........",
"X.........X",
"X.........X",
".XX..K..XX.",
]
.try_into()?;
assert_eq!(board.closed_off_exits(), 4);
Ok(())
}
#[test]
fn someone_wins() {
let mut game = Game::default();
let mut ai: Box<dyn AI> = Box::new(AiBanal);
loop {
if ai.generate_move(&mut game).is_err() {
break;
}
}
assert!(game.status == Status::AttackerWins || game.status == Status::DefenderWins);
}