From 6e483b412bfd94f8178134fa2e81544a15d965a0 Mon Sep 17 00:00:00 2001 From: Eryn Wells Date: Sat, 6 Jan 2024 19:47:55 -0800 Subject: [PATCH] [board] Refactor ray BitBoard lookups Rearrange the generated ray bitboards into a 2D grid by square and direction. Use the Direction vector for lookup. --- board/src/bitboard/bitboard.rs | 4 ++ board/src/bitboard/library.rs | 119 ++++++++++++--------------------- 2 files changed, 47 insertions(+), 76 deletions(-) diff --git a/board/src/bitboard/bitboard.rs b/board/src/bitboard/bitboard.rs index 946b4e0..3a31a0e 100644 --- a/board/src/bitboard/bitboard.rs +++ b/board/src/bitboard/bitboard.rs @@ -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); diff --git a/board/src/bitboard/library.rs b/board/src/bitboard/library.rs index 95a4bf2..697d12a 100644 --- a/board/src/bitboard/library.rs +++ b/board/src/bitboard/library.rs @@ -1,7 +1,7 @@ // Eryn Wells 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);