[bitboard, board] Replace ray_in_direction! macro with a function
This is simpler than writing a macro, at the expense of some overhead for calling a function. But the Rust compiler might inline it anyway! To support this change, implement BitBoard::first_occupied_square_direction, which iterates a bitboard in a direction (i.e. leading or trailing) depending on the core::Direction value passed to it.
This commit is contained in:
		
							parent
							
								
									e3d17219ad
								
							
						
					
					
						commit
						a904e4a5bb
					
				
					 2 changed files with 41 additions and 33 deletions
				
			
		|  | @ -243,6 +243,18 @@ impl BitBoard { | |||
|         TrailingBitScanner::new(self.0) | ||||
|     } | ||||
| 
 | ||||
|     #[must_use] | ||||
|     pub fn first_occupied_square_direction(&self, direction: Direction) -> Option<Square> { | ||||
|         match direction { | ||||
|             Direction::North | Direction::NorthEast | Direction::NorthWest | Direction::East => { | ||||
|                 self.first_occupied_square_trailing() | ||||
|             } | ||||
|             Direction::SouthEast | Direction::South | Direction::SouthWest | Direction::West => { | ||||
|                 self.first_occupied_square_leading() | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     #[must_use] | ||||
|     pub fn first_occupied_square(&self, direction: &IterationDirection) -> Option<Square> { | ||||
|         match direction { | ||||
|  |  | |||
|  | @ -138,20 +138,6 @@ struct SightInfo { | |||
|     friendly_occupancy: BitBoard, | ||||
| } | ||||
| 
 | ||||
| macro_rules! ray_in_direction { | ||||
|     ($square:expr, $blockers:expr, $direction:ident, $first_occupied_square:tt) => {{ | ||||
|         let ray = BitBoard::ray($square, Direction::$direction); | ||||
|         let ray_blockers = ray & $blockers; | ||||
|         if let Some(first_occupied_square) = ray_blockers.$first_occupied_square() { | ||||
|             let remainder = BitBoard::ray(first_occupied_square, Direction::$direction); | ||||
|             let attack_ray = ray & !remainder; | ||||
|             attack_ray | ||||
|         } else { | ||||
|             ray | ||||
|         } | ||||
|     }}; | ||||
| } | ||||
| 
 | ||||
| /// Compute sight of a white pawn.
 | ||||
| fn white_pawn_sight(info: &SightInfo, en_passant_square: BitBoard) -> BitBoard { | ||||
|     let possible_squares = !info.friendly_occupancy | en_passant_square; | ||||
|  | @ -175,15 +161,27 @@ fn knight_sight(info: &SightInfo) -> BitBoard { | |||
|     BitBoard::knight_moves(info.square) | ||||
| } | ||||
| 
 | ||||
| fn ray_in_direction(square: Square, blockers: BitBoard, direction: Direction) -> BitBoard { | ||||
|     let ray = BitBoard::ray(square, direction); | ||||
| 
 | ||||
|     let ray_blockers = ray & blockers; | ||||
|     if let Some(first_occupied_square) = ray_blockers.first_occupied_square_direction(direction) { | ||||
|         let remainder = BitBoard::ray(first_occupied_square, direction); | ||||
|         let attack_ray = ray & !remainder; | ||||
|         attack_ray | ||||
|     } else { | ||||
|         ray | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn bishop_sight(info: &SightInfo) -> BitBoard { | ||||
|     let bishop = info.square; | ||||
|     let occupancy = info.occupancy; | ||||
| 
 | ||||
|     #[rustfmt::skip] | ||||
|     let sight = ray_in_direction!(bishop, occupancy, NorthEast, first_occupied_square_trailing) | ||||
|         | ray_in_direction!(bishop, occupancy, SouthEast, first_occupied_square_leading) | ||||
|         | ray_in_direction!(bishop, occupancy, SouthWest, first_occupied_square_leading) | ||||
|         | ray_in_direction!(bishop, occupancy, NorthWest, first_occupied_square_trailing); | ||||
|     let sight = ray_in_direction(bishop, occupancy, Direction::NorthEast) | ||||
|         | ray_in_direction(bishop, occupancy, Direction::SouthEast) | ||||
|         | ray_in_direction(bishop, occupancy, Direction::SouthWest) | ||||
|         | ray_in_direction(bishop, occupancy, Direction::NorthWest); | ||||
| 
 | ||||
|     sight | ||||
| } | ||||
|  | @ -192,11 +190,10 @@ fn rook_sight(info: &SightInfo) -> BitBoard { | |||
|     let rook = info.square; | ||||
|     let occupancy = info.occupancy; | ||||
| 
 | ||||
|     #[rustfmt::skip] | ||||
|     let sight = ray_in_direction!(rook, occupancy, North, first_occupied_square_trailing) | ||||
|         | ray_in_direction!(rook, occupancy, East, first_occupied_square_trailing) | ||||
|         | ray_in_direction!(rook, occupancy, South, first_occupied_square_leading) | ||||
|         | ray_in_direction!(rook, occupancy, West, first_occupied_square_leading); | ||||
|     let sight = ray_in_direction(rook, occupancy, Direction::North) | ||||
|         | ray_in_direction(rook, occupancy, Direction::East) | ||||
|         | ray_in_direction(rook, occupancy, Direction::South) | ||||
|         | ray_in_direction(rook, occupancy, Direction::West); | ||||
| 
 | ||||
|     sight | ||||
| } | ||||
|  | @ -205,15 +202,14 @@ fn queen_sight(info: &SightInfo) -> BitBoard { | |||
|     let queen = info.square; | ||||
|     let occupancy = info.occupancy; | ||||
| 
 | ||||
|     #[rustfmt::skip] | ||||
|     let sight = ray_in_direction!(queen, occupancy, NorthWest, first_occupied_square_trailing) | ||||
|         | ray_in_direction!(queen, occupancy, North, first_occupied_square_trailing) | ||||
|         | ray_in_direction!(queen, occupancy, NorthEast, first_occupied_square_trailing) | ||||
|         | ray_in_direction!(queen, occupancy, East, first_occupied_square_trailing) | ||||
|         | ray_in_direction!(queen, occupancy, SouthEast, first_occupied_square_leading) | ||||
|         | ray_in_direction!(queen, occupancy, South, first_occupied_square_leading) | ||||
|         | ray_in_direction!(queen, occupancy, SouthWest, first_occupied_square_leading) | ||||
|         | ray_in_direction!(queen, occupancy, West, first_occupied_square_leading); | ||||
|     let sight = ray_in_direction(queen, occupancy, Direction::NorthWest) | ||||
|         | ray_in_direction(queen, occupancy, Direction::North) | ||||
|         | ray_in_direction(queen, occupancy, Direction::NorthEast) | ||||
|         | ray_in_direction(queen, occupancy, Direction::East) | ||||
|         | ray_in_direction(queen, occupancy, Direction::SouthEast) | ||||
|         | ray_in_direction(queen, occupancy, Direction::South) | ||||
|         | ray_in_direction(queen, occupancy, Direction::SouthWest) | ||||
|         | ray_in_direction(queen, occupancy, Direction::West); | ||||
| 
 | ||||
|     sight | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue