145 lines
No EOL
4.9 KiB
Rust
145 lines
No EOL
4.9 KiB
Rust
use chess_engine::board::Board;
|
|
use chess_engine::movegen::non_sliders::generate_king_moves;
|
|
use chess_engine::r#move::MoveList;
|
|
|
|
/// Compares two move list strings ignoring the order of moves.
|
|
fn assert_moves_equal(actual_str: &str, expected_str: &str) {
|
|
let mut actual_moves: Vec<&str> = actual_str.split_whitespace().collect();
|
|
let mut expected_moves: Vec<&str> = expected_str.split_whitespace().collect();
|
|
|
|
actual_moves.sort();
|
|
expected_moves.sort();
|
|
|
|
assert_eq!(actual_moves, expected_moves);
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_start_pos_blocked() {
|
|
let fen_standard = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
|
let board = Board::from_fen(fen_standard);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// King is completely blocked in the start position
|
|
assert_moves_equal(&list.to_string(), "");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_center() {
|
|
let fen = "8/8/8/8/4K3/8/8/8 w - - 0 1"; // King on e4
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// 8 moves from e4
|
|
assert_moves_equal(&list.to_string(), "e4d3 e4d4 e4d5 e4e3 e4e5 e4f3 e4f4 e4f5");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_corner() {
|
|
let fen = "K7/8/8/8/8/8/8/8 w - - 0 1"; // King on a8
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// 3 moves from a8
|
|
assert_moves_equal(&list.to_string(), "a8a7 a8b7 a8b8");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_blocked_friendly() {
|
|
// King on d4, surrounded by friendly pawns
|
|
let fen = "8/8/8/3P1P2/3K4/3P1P2/8/8 w - - 0 1";
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// d3, d5, f3, f5 are blocked.
|
|
// c3, c4, c5, e3, e4, e5 are free.
|
|
assert_moves_equal(&list.to_string(), "d4c3 d4c4 d4c5 d4e3 d4e4 d4e5");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_capture_and_blocked() {
|
|
// King on d4
|
|
// Friendly: c3, e5
|
|
// Enemy: c5, e3
|
|
let fen = "8/8/8/2p1P3/3K4/2P1p3/8/8 w - - 0 1";
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// Blocked: c3, e5
|
|
// Captures: c5, e3
|
|
// Empty: c4, d3, d5, e4, f3, f4, f5
|
|
// Note: f3, f4, f5 are valid moves
|
|
assert_moves_equal(&list.to_string(), "d4c4 d4d3 d4d5 d4e4 d4c5 d4e3");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_black() {
|
|
let fen = "8/8/8/8/4k3/8/8/8 b - - 0 1"; // Black king on e4
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// 8 moves from e4
|
|
assert_moves_equal(&list.to_string(), "e4d3 e4d4 e4d5 e4e3 e4e5 e4f3 e4f4 e4f5");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_castling_white_all() {
|
|
// King on e1, rooks on a1, h1. All rights. No pieces between.
|
|
let fen = "r3k2r/8/8/8/8/8/8/R3K2R w KQkq - 0 1";
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// 5 standard moves + 2 castling moves (e1g1, e1c1)
|
|
assert_moves_equal(&list.to_string(), "e1d1 e1d2 e1e2 e1f1 e1f2 O-O O-O-O");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_castling_black_all() {
|
|
// King on e8, rooks on a8, h8. All rights. No pieces between.
|
|
let fen = "r3k2r/8/8/8/8/8/8/R3K2R b KQkq - 0 1";
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// 5 standard moves + 2 castling moves (e8g8, e8c8)
|
|
assert_moves_equal(&list.to_string(), "O-O O-O-O e8d8 e8e7 e8f8 e8d7 e8f7");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_castling_blocked_pieces_white() {
|
|
// White: Queenside blocked by knight
|
|
let fen = "r3k2r/8/8/8/8/8/8/RN2K2R w KQkq - 0 1";
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// Should only get Kingside castling (e1g1) and standard moves
|
|
assert_moves_equal(&list.to_string(), "e1d1 e1d2 e1e2 e1f1 e1f2 O-O");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_castling_blocked_pieces_black() {
|
|
// Black: Kingside blocked by bishop
|
|
let fen = "r3kb1r/8/8/8/8/8/8/R3K2R b KQkq - 0 1";
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
assert_moves_equal(&list.to_string(), "e8d8 e8d7 e8e7 e8f7 O-O-O");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_castling_no_rights() {
|
|
// Same as `test_king_moves_castling_white_all` but no castling rights
|
|
let fen = "r3k2r/8/8/8/8/8/8/R3K2R w - - 0 1";
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
// 5 standard moves, 0 castling
|
|
assert_moves_equal(&list.to_string(), "e1d1 e1d2 e1e2 e1f1 e1f2");
|
|
}
|
|
|
|
#[test]
|
|
fn test_king_moves_empty_board() {
|
|
let fen = "8/8/8/8/8/8/8/8 w - - 0 1";
|
|
let board = Board::from_fen(fen);
|
|
let mut list = MoveList::new();
|
|
generate_king_moves(&board, &mut list);
|
|
assert_moves_equal(&list.to_string(), "");
|
|
} |