[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:
Eryn Wells 2025-06-30 15:37:35 -07:00
parent e3d17219ad
commit a904e4a5bb
2 changed files with 41 additions and 33 deletions

View file

@ -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
}