diff --git a/board/src/position/position.rs b/board/src/position/position.rs index 0356e94..dcb4f7f 100644 --- a/board/src/position/position.rs +++ b/board/src/position/position.rs @@ -236,6 +236,12 @@ impl Position { .next() .unwrap(); sight_of_opposing_player.is_set(king_square) +} + +#[cfg(test)] +impl Position { + pub(crate) fn test_set_en_passant_square(&mut self, square: Square) { + self.en_passant_square = Some(square); } } diff --git a/board/src/sight.rs b/board/src/sight.rs index 33e716e..46d88b4 100644 --- a/board/src/sight.rs +++ b/board/src/sight.rs @@ -153,3 +153,108 @@ impl PlacedPiece { BitBoard::king_moves(self.square()) & !position.friendly_pieces() } } + +#[cfg(test)] +mod tests { + macro_rules! sight_test { + ($test_name:ident, $position:expr, $piece:expr, $bitboard:expr) => { + #[test] + fn $test_name() { + let pos = $position; + let pp = $piece; + let sight = pp.sight_in_position(&pos); + + assert_eq!(sight, $bitboard); + } + }; + ($test_name:ident, $piece:expr, $bitboard:expr) => { + sight_test! {$test_name, $crate::Position::empty(), $piece, $bitboard} + }; + } + + mod pawn { + use crate::{position, sight::Sight, BitBoard, Position, Square}; + + sight_test!(e4_pawn, piece!(White Pawn on E4), bitboard!(D5, F5)); + + sight_test!( + e4_pawn_one_blocker, + position![ + White Bishop on D5, + White Pawn on E4, + ], + piece!(White Pawn on E4), + bitboard!(F5) + ); + + #[test] + fn e4_pawn_two_blocker() { + let pos = position!( + White Bishop on D5, + White Queen on F5, + White Pawn on E4, + ); + let pp = piece!(White Pawn on E4); + let sight = pp.sight_in_position(&pos); + + assert_eq!(sight, BitBoard::empty()); + } + + #[test] + fn e4_pawn_capturable() { + let pos = position!( + Black Bishop on D5, + White Queen on F5, + White Pawn on E4, + ); + let pp = piece!(White Pawn on E4); + let sight = pp.sight_in_position(&pos); + + assert_eq!(sight, bitboard!(D5)); + } + + #[test] + fn e5_en_passant() { + let mut pos = position!( + White Pawn on E5, + Black Pawn on D5, + ); + pos.test_set_en_passant_square(Square::D6); + let pp = piece!(White Pawn on E5); + let sight = pp.sight_in_position(&pos); + + assert_eq!(sight, bitboard!(D6, F6)); + } + } + + #[macro_use] + mod knight { + use crate::{sight::Sight, Position}; + + sight_test!( + f6_knight, + piece!(Black Knight on F6), + bitboard!(H7, G8, E8, D7, D5, E4, G4, H5) + ); + } + + mod bishop { + use crate::sight::Sight; + + sight_test!( + c2_bishop, + piece!(Black Bishop on C2), + bitboard!(D1, B3, A4, B1, D3, E4, F5, G6, H7) + ); + } + + mod rook { + use crate::sight::Sight; + + sight_test!( + g3_rook, + piece!(White Rook on G3), + bitboard!(G1, G2, G4, G5, G6, G7, G8, A3, B3, C3, D3, E3, F3, H3) + ); + } +}