From ac07a8d6cfa6bca72f9581abe460a964197f4015 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Fri, 2 Feb 2024 07:29:43 -0800 Subject: [PATCH] [position] Implement SliderRayToSquareExt on Shape instead of PlacedPiece Add an origin square argument to its one method ::ray_to_square(). Pushing this implementation down a layer means I don't have to care about the color of the piece. --- position/src/sight.rs | 72 +++++++++++++++++-------------------------- 1 file changed, 29 insertions(+), 43 deletions(-) diff --git a/position/src/sight.rs b/position/src/sight.rs index 27cb53d..056ae45 100644 --- a/position/src/sight.rs +++ b/position/src/sight.rs @@ -41,7 +41,7 @@ pub(crate) trait SightExt { } pub(crate) trait SliderRayToSquareExt { - fn ray_to_square(&self, square: Square) -> Option; + fn ray_to_square(&self, origin: Square, target: Square) -> Option; } impl SightExt for PlacedPiece { @@ -156,8 +156,8 @@ impl SightExt for PlacedPiece { } } -impl SliderRayToSquareExt for PlacedPiece { - fn ray_to_square(&self, target: Square) -> Option { +impl SliderRayToSquareExt for Shape { + fn ray_to_square(&self, origin: Square, target: Square) -> Option { macro_rules! ray { ($square:expr, $direction:ident) => { ( @@ -167,35 +167,34 @@ impl SliderRayToSquareExt for PlacedPiece { }; } - let square = self.square(); let target_bitboard: BitBoard = target.into(); - let ray_and_direction = match self.shape() { + let ray_and_direction = match self { Shape::Bishop => [ - ray!(square, NorthEast), - ray!(square, SouthEast), - ray!(square, SouthWest), - ray!(square, NorthWest), + ray!(origin, NorthEast), + ray!(origin, SouthEast), + ray!(origin, SouthWest), + ray!(origin, NorthWest), ] .into_iter() .find(|(&ray, _)| !(target_bitboard & ray).is_empty()), Shape::Rook => [ - ray!(square, North), - ray!(square, East), - ray!(square, South), - ray!(square, West), + ray!(origin, North), + ray!(origin, East), + ray!(origin, South), + ray!(origin, West), ] .into_iter() .find(|(&ray, _)| !(target_bitboard & ray).is_empty()), Shape::Queen => [ - ray!(square, North), - ray!(square, NorthEast), - ray!(square, East), - ray!(square, SouthEast), - ray!(square, South), - ray!(square, SouthWest), - ray!(square, West), - ray!(square, NorthWest), + ray!(origin, North), + ray!(origin, NorthEast), + ray!(origin, East), + ray!(origin, SouthEast), + ray!(origin, South), + ray!(origin, SouthWest), + ray!(origin, West), + ray!(origin, NorthWest), ] .into_iter() .find(|(&ray, _)| !(target_bitboard & ray).is_empty()), @@ -203,21 +202,8 @@ impl SliderRayToSquareExt for PlacedPiece { }; if let Some((ray, direction)) = ray_and_direction { - let first_occupied_square = match direction { - Direction::East - | Direction::NorthWest - | Direction::NorthEast - | Direction::North => ray.first_occupied_square_trailing(), - Direction::West - | Direction::SouthWest - | Direction::SouthEast - | Direction::South => ray.first_occupied_square(), - }; - - if let Some(occupied_square) = first_occupied_square { - let remainder = BitBoard::ray(target, direction); - return Some(ray & !remainder); - } + let remainder = BitBoard::ray(target, direction); + return Some(ray & !remainder); } None @@ -248,8 +234,8 @@ mod tests { #[test] fn pawns_and_knights_cannot_make_rays() { - assert_eq!(piece!(White Pawn on F7).ray_to_square(Square::E8), None); - assert_eq!(piece!(White Knight on F6).ray_to_square(Square::E8), None); + assert_eq!(Shape::Pawn.ray_to_square(Square::F7, Square::E8), None); + assert_eq!(Shape::Knight.ray_to_square(Square::F6, Square::E8), None); } mod pawn { @@ -334,7 +320,7 @@ mod tests { #[test] fn ray_to_square() { - let generated_ray = piece!(White Bishop on C5).ray_to_square(Square::E7); + let generated_ray = Shape::Bishop.ray_to_square(Square::C5, Square::E7); let expected_ray = bitboard![D6, E7]; assert_eq!(generated_ray, Some(expected_ray)); } @@ -363,19 +349,19 @@ mod tests { #[test] fn ray_to_square() { - let generated_ray = piece!(White Rook on C2).ray_to_square(Square::C6); + let generated_ray = Shape::Rook.ray_to_square(Square::C2, Square::C6); let expected_ray = bitboard![C3, C4, C5, C6]; assert_eq!(generated_ray, Some(expected_ray)); - let generated_ray = piece!(White Rook on D2).ray_to_square(Square::H2); + let generated_ray = Shape::Rook.ray_to_square(Square::D2, Square::H2); let expected_ray = bitboard![E2, F2, G2, H2]; assert_eq!(generated_ray, Some(expected_ray)); - let generated_ray = piece!(White Rook on G6).ray_to_square(Square::B6); + let generated_ray = Shape::Rook.ray_to_square(Square::G6, Square::B6); let expected_ray = bitboard![B6, C6, D6, E6, F6]; assert_eq!(generated_ray, Some(expected_ray)); - let generated_ray = piece!(White Rook on A6).ray_to_square(Square::A3); + let generated_ray = Shape::Rook.ray_to_square(Square::A6, Square::A3); let expected_ray = bitboard![A5, A4, A3]; assert_eq!(generated_ray, Some(expected_ray)); }