[board] Refactor ray BitBoard lookups

Rearrange the generated ray bitboards into a 2D grid by square and direction.
Use the Direction vector for lookup.
This commit is contained in:
Eryn Wells 2024-01-06 19:47:55 -08:00
parent 2394afc210
commit 6e483b412b
2 changed files with 47 additions and 76 deletions

View file

@ -36,6 +36,10 @@ impl BitBoard {
FILES[file]
}
pub fn ray(sq: Square, dir: Direction) -> BitBoard {
library().ray(sq, dir)
}
moves_getter!(knight_moves);
moves_getter!(bishop_moves);
moves_getter!(rook_moves);

View file

@ -1,7 +1,7 @@
// Eryn Wells <eryn@erynwells.me>
use super::BitBoard;
use crate::Square;
use crate::{square::Direction, Square};
use std::sync::Once;
pub(super) const RANKS: [BitBoard; 8] = [
@ -26,8 +26,9 @@ pub(super) const FILES: [BitBoard; 8] = [
BitBoard(0x0101010101010101 << 7),
];
static mut MOVE_LIBRARY: MoveLibrary = MoveLibrary::new();
static MOVE_LIBRARY_INIT: Once = Once::new();
pub(super) const LIGHT_SQUARES: BitBoard =
BitBoard(0x5555 | 0x5555 << 16 | 0x5555 << 32 | 0x5555 << 48);
pub(super) const DARK_SQUARES: BitBoard = BitBoard(!LIGHT_SQUARES.0);
pub(super) fn library() -> &'static MoveLibrary {
static MOVE_LIBRARY_INIT: Once = Once::new();
@ -42,44 +43,6 @@ pub(super) fn library() -> &'static MoveLibrary {
}
}
#[derive(Clone, Copy, Debug)]
struct OrthogonalRays {
positive_rank: BitBoard,
positive_file: BitBoard,
negative_rank: BitBoard,
negative_file: BitBoard,
}
impl OrthogonalRays {
const fn new() -> OrthogonalRays {
OrthogonalRays {
positive_rank: BitBoard::empty(),
positive_file: BitBoard::empty(),
negative_rank: BitBoard::empty(),
negative_file: BitBoard::empty(),
}
}
}
#[derive(Clone, Copy, Debug)]
struct DiagonalRays {
positive_diagonal: BitBoard,
positive_antidiagonal: BitBoard,
negative_diagonal: BitBoard,
negative_antidiagonal: BitBoard,
}
impl DiagonalRays {
const fn new() -> DiagonalRays {
DiagonalRays {
positive_diagonal: BitBoard::empty(),
positive_antidiagonal: BitBoard::empty(),
negative_diagonal: BitBoard::empty(),
negative_antidiagonal: BitBoard::empty(),
}
}
}
macro_rules! library_getter {
($name:ident) => {
pub(super) fn $name(&self, sq: Square) -> BitBoard {
@ -91,8 +54,7 @@ macro_rules! library_getter {
#[derive(Debug)]
pub(super) struct MoveLibrary {
// Rays
diagonal_rays: [DiagonalRays; Square::NUM as usize],
orthogonal_rays: [OrthogonalRays; Square::NUM as usize],
rays: [[BitBoard; 8]; Square::NUM],
// Piecewise move tables
knight_moves: [BitBoard; 64],
@ -105,8 +67,7 @@ pub(super) struct MoveLibrary {
impl MoveLibrary {
const fn new() -> MoveLibrary {
MoveLibrary {
diagonal_rays: [DiagonalRays::new(); 64],
orthogonal_rays: [OrthogonalRays::new(); 64],
rays: [[BitBoard::empty(); 8]; Square::NUM],
knight_moves: [BitBoard::empty(); 64],
bishop_moves: [BitBoard::empty(); 64],
rook_moves: [BitBoard::empty(); 64],
@ -120,31 +81,33 @@ impl MoveLibrary {
self.init_orthogonal_rays(sq);
self.init_diagonal_rays(sq);
self.init_knight_moves(sq as usize);
self.init_bishop_moves(sq as usize);
self.init_rook_moves(sq as usize);
self.init_queen_moves(sq as usize);
self.init_bishop_moves(sq);
self.init_rook_moves(sq);
self.init_queen_moves(sq);
self.init_king_moves(sq as usize);
}
}
fn init_orthogonal_rays(&mut self, sq: Square) {
let sq_bb: BitBoard = sq.into();
let ortho_rays = &mut self.orthogonal_rays[sq as usize];
ortho_rays.positive_file = Self::generate_ray(sq_bb, BitBoard::shift_north_one);
ortho_rays.negative_file = Self::generate_ray(sq_bb, BitBoard::shift_south_one);
ortho_rays.positive_rank = Self::generate_ray(sq_bb, BitBoard::shift_east_one);
ortho_rays.negative_rank = Self::generate_ray(sq_bb, BitBoard::shift_west_one);
let rays = &mut self.rays[sq as usize];
rays[Direction::North as usize] = Self::generate_ray(sq_bb, BitBoard::shift_north_one);
rays[Direction::South as usize] = Self::generate_ray(sq_bb, BitBoard::shift_south_one);
rays[Direction::East as usize] = Self::generate_ray(sq_bb, BitBoard::shift_east_one);
rays[Direction::West as usize] = Self::generate_ray(sq_bb, BitBoard::shift_west_one);
}
fn init_diagonal_rays(&mut self, sq: Square) {
let sq_bb: BitBoard = sq.into();
let diag_rays = &mut self.diagonal_rays[sq as usize];
diag_rays.positive_diagonal = Self::generate_ray(sq_bb, BitBoard::shift_north_east_one);
diag_rays.positive_antidiagonal = Self::generate_ray(sq_bb, BitBoard::shift_north_west_one);
diag_rays.negative_diagonal = Self::generate_ray(sq_bb, BitBoard::shift_south_west_one);
diag_rays.negative_antidiagonal = Self::generate_ray(sq_bb, BitBoard::shift_south_east_one);
let rays = &mut self.rays[sq as usize];
rays[Direction::NorthEast as usize] =
Self::generate_ray(sq_bb, BitBoard::shift_north_east_one);
rays[Direction::NorthWest as usize] =
Self::generate_ray(sq_bb, BitBoard::shift_north_west_one);
rays[Direction::SouthWest as usize] =
Self::generate_ray(sq_bb, BitBoard::shift_south_west_one);
rays[Direction::SouthEast as usize] =
Self::generate_ray(sq_bb, BitBoard::shift_south_east_one);
}
fn init_king_moves(&mut self, idx: usize) {
@ -179,26 +142,26 @@ impl MoveLibrary {
self.knight_moves[idx] = attacks;
}
fn init_bishop_moves(&mut self, idx: usize) {
let diag_rays = self.diagonal_rays[idx];
self.bishop_moves[idx] = diag_rays.positive_diagonal
| diag_rays.negative_diagonal
| diag_rays.positive_antidiagonal
| diag_rays.negative_antidiagonal;
fn init_bishop_moves(&mut self, sq: Square) {
let rays = self.rays[sq as usize];
self.bishop_moves[sq as usize] = rays[Direction::NorthWest as usize]
| rays[Direction::NorthEast as usize]
| rays[Direction::SouthEast as usize]
| rays[Direction::SouthWest as usize];
}
fn init_rook_moves(&mut self, idx: usize) {
let ortho_rays = self.orthogonal_rays[idx];
self.rook_moves[idx] = ortho_rays.positive_rank
| ortho_rays.negative_rank
| ortho_rays.positive_file
| ortho_rays.negative_file;
fn init_rook_moves(&mut self, sq: Square) {
let rays = self.rays[sq as usize];
self.rook_moves[sq as usize] = rays[Direction::North as usize]
| rays[Direction::East as usize]
| rays[Direction::South as usize]
| rays[Direction::West as usize];
}
fn init_queen_moves(&mut self, idx: usize) {
let rook_moves = self.rook_moves[idx];
let bishop_moves = self.bishop_moves[idx];
self.queen_moves[idx] = rook_moves | bishop_moves;
fn init_queen_moves(&mut self, sq: Square) {
let rook_moves = self.rook_moves[sq as usize];
let bishop_moves = self.bishop_moves[sq as usize];
self.queen_moves[sq as usize] = rook_moves | bishop_moves;
}
#[inline]
@ -214,6 +177,10 @@ impl MoveLibrary {
ray
}
pub(super) fn ray(&self, sq: Square, dir: Direction) -> BitBoard {
self.rays[sq as usize][dir as usize]
}
library_getter!(knight_moves);
library_getter!(bishop_moves);
library_getter!(rook_moves);