#[cfg(test)]
mod integration_tests {
use micattix::core::{Board, BoardSize, GameMode, Piece, Player};
use micattix::game::{GameEvent, GameEventListener, GameManager};
use std::collections::VecDeque;
struct SimpleEventRecorder {
events: VecDeque<GameEvent>,
}
impl SimpleEventRecorder {
fn new() -> Self {
Self {
events: VecDeque::new(),
}
}
}
impl GameEventListener for SimpleEventRecorder {
fn on_event(&mut self, event: GameEvent) {
self.events.push_back(event);
}
}
#[test]
fn test_two_player_game_flow() {
let mut manager = GameManager::new(BoardSize::Small, GameMode::TwoPlayers);
let _recorder = SimpleEventRecorder::new();
manager.start_game();
let valid_moves = manager.session.board.get_valid_moves(Player::First);
assert!(!valid_moves.is_empty());
let move_target = valid_moves[0];
manager.make_move(move_target);
assert_eq!(manager.session.current_player, Player::Second);
}
#[test]
fn test_four_player_game_flow() {
let mut manager = GameManager::new(BoardSize::Small, GameMode::FourPlayers);
manager.start_game();
assert_eq!(manager.session.current_player, Player::First);
for expected_player in [Player::First, Player::Second, Player::Third, Player::Fourth] {
assert_eq!(manager.session.current_player, expected_player);
let valid_moves = manager.session.board.get_valid_moves(expected_player);
if valid_moves.is_empty() {
continue;
}
let move_target = valid_moves[0];
manager.make_move(move_target);
}
assert_eq!(manager.session.current_player, Player::First);
}
#[test]
fn test_game_round_completion() {
let mut board = Board::new(BoardSize::Small);
let cross_pos = board.cross_position;
for row in 0..4 {
for col in 0..4 {
if (row, col) != cross_pos {
board.set_piece(row, col, Piece::Empty);
}
}
}
let target_col = (cross_pos.1 + 1) % 4; board.set_piece(cross_pos.0, target_col, Piece::Number(5));
let mut manager = GameManager::new_with_board(board, GameMode::TwoPlayers);
manager.session.current_player = Player::First;
manager.start_game();
let valid_moves = manager
.session
.board
.get_valid_moves(manager.session.current_player);
println!("Cross position: {:?}", cross_pos);
println!("Valid moves: {:?}", valid_moves);
println!("Current player: {:?}", manager.session.current_player);
println!("Board state:");
println!("{}", manager.session.board.display());
assert_eq!(valid_moves.len(), 1, "Should have exactly one valid move");
let target = valid_moves[0];
manager.make_move(target);
assert!(
manager.session.is_round_over(),
"Round should be over after taking the last piece"
);
manager.start_next_round();
assert_eq!(manager.session.round, 2);
}
#[test]
fn test_four_player_score_calculation() {
let mut manager = GameManager::new(BoardSize::Small, GameMode::FourPlayers);
manager.start_game();
for player in [Player::First, Player::Second, Player::Third, Player::Fourth] {
assert_eq!(manager.session.current_player, player);
let valid_moves = manager.session.board.get_valid_moves(player);
if valid_moves.is_empty() {
continue; }
let before_score = manager.session.scores.get(&player).unwrap().total;
let target = valid_moves[0];
let piece_value = match manager.session.board.get_piece(target.0, target.1) {
Piece::Number(val) => val,
_ => 0,
};
manager.make_move(target);
if piece_value != 0 {
let after_score = manager.session.scores.get(&player).unwrap().total;
assert_eq!(after_score - before_score, piece_value);
}
}
}
#[test]
fn test_invalid_moves() {
let mut manager = GameManager::new(BoardSize::Small, GameMode::TwoPlayers);
manager.start_game();
let cross_pos = manager.session.board.cross_position;
let result1 = manager.session.process_move(cross_pos);
assert!(result1.is_err(), "Move to cross position should fail");
let result2 = manager.session.process_move((10, 10));
assert!(result2.is_err(), "Move outside board should fail");
}
#[test]
fn test_score_calculation() {
let mut manager = GameManager::new(BoardSize::Small, GameMode::TwoPlayers);
manager.start_game();
let valid_moves = manager.session.board.get_valid_moves(Player::First);
let move_target = valid_moves[0];
let before_score = manager.session.scores.get(&Player::First).unwrap().total;
let piece_value = match manager
.session
.board
.get_piece(move_target.0, move_target.1)
{
Piece::Number(val) => val,
_ => 0,
};
manager.make_move(move_target);
let after_score = manager.session.scores.get(&Player::First).unwrap().total;
assert_eq!(after_score - before_score, piece_value);
}
#[test]
fn test_game_mode_players() {
let two_player_manager = GameManager::new(BoardSize::Small, GameMode::TwoPlayers);
assert_eq!(two_player_manager.session.players.len(), 2);
assert!(two_player_manager.session.players.contains(&Player::First));
assert!(two_player_manager.session.players.contains(&Player::Second));
assert!(!two_player_manager.session.players.contains(&Player::Third));
assert!(!two_player_manager.session.players.contains(&Player::Fourth));
let four_player_manager = GameManager::new(BoardSize::Small, GameMode::FourPlayers);
assert_eq!(four_player_manager.session.players.len(), 4);
assert!(four_player_manager.session.players.contains(&Player::First));
assert!(four_player_manager
.session
.players
.contains(&Player::Second));
assert!(four_player_manager.session.players.contains(&Player::Third));
assert!(four_player_manager
.session
.players
.contains(&Player::Fourth));
}
#[test]
fn test_player_direction() {
assert_eq!(
Player::First.direction(),
micattix::core::MoveDirection::Horizontal
);
assert_eq!(
Player::Third.direction(),
micattix::core::MoveDirection::Horizontal
);
assert_eq!(
Player::Second.direction(),
micattix::core::MoveDirection::Vertical
);
assert_eq!(
Player::Fourth.direction(),
micattix::core::MoveDirection::Vertical
);
}
}