[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