Improve attack table init, add inline to fetch fns
This commit is contained in:
@@ -35,9 +35,8 @@ pub const BISHOP_RELEVANT_BITS: [usize; 64] = [
|
||||
static PAWN_ATTACKS: LazyLock<[[Bitboard; 2]; 64]> = LazyLock::new(init_pawn_attacks);
|
||||
static KNIGHT_ATTACKS: LazyLock<[Bitboard; 64]> = LazyLock::new(init_knight_attacks);
|
||||
static KING_ATTACKS: LazyLock<[Bitboard; 64]> = LazyLock::new(init_king_attacks);
|
||||
static BISHOP_ATTACKS: LazyLock<Box<[[Bitboard; 512]; 64]>> = LazyLock::new(init_bishop_attacks);
|
||||
static ROOK_ATTACKS: LazyLock<HashMap<usize, HashMap<usize, u64>>> =
|
||||
LazyLock::new(init_rook_attacks);
|
||||
static BISHOP_ATTACKS: LazyLock<Vec<Vec<Bitboard>>> = LazyLock::new(init_bishop_attacks);
|
||||
static ROOK_ATTACKS: LazyLock<Vec<Vec<Bitboard>>> = LazyLock::new(init_rook_attacks);
|
||||
|
||||
const fn pawn_attacks(bitboard: Bitboard, color: Color) -> Bitboard {
|
||||
let mut attacks = EMPTY;
|
||||
@@ -86,7 +85,7 @@ const fn king_attacks(bitboard: Bitboard) -> Bitboard {
|
||||
attacks
|
||||
}
|
||||
|
||||
pub fn mask_bishop_attacks(bitboard: Bitboard) -> Bitboard {
|
||||
fn mask_bishop_attacks(bitboard: Bitboard) -> Bitboard {
|
||||
let mut attacks = EMPTY;
|
||||
let (rank_dst, file_dst) = bitboard_to_coords(bitboard);
|
||||
|
||||
@@ -109,7 +108,7 @@ pub fn mask_bishop_attacks(bitboard: Bitboard) -> Bitboard {
|
||||
attacks
|
||||
}
|
||||
|
||||
pub fn mask_rook_attacks(bitboard: Bitboard) -> Bitboard {
|
||||
fn mask_rook_attacks(bitboard: Bitboard) -> Bitboard {
|
||||
let mut attacks = EMPTY;
|
||||
let (rank_dst, file_dst) = bitboard_to_coords(bitboard);
|
||||
|
||||
@@ -135,7 +134,7 @@ pub fn mask_rook_attacks(bitboard: Bitboard) -> Bitboard {
|
||||
attacks
|
||||
}
|
||||
|
||||
pub fn bishop_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboard {
|
||||
fn bishop_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboard {
|
||||
let mut attacks = EMPTY;
|
||||
let (rank_dst, file_dst) = bitboard_to_coords(bitboard);
|
||||
|
||||
@@ -164,7 +163,7 @@ pub fn bishop_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitbo
|
||||
attacks
|
||||
}
|
||||
|
||||
pub fn rook_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboard {
|
||||
fn rook_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboard {
|
||||
let mut attacks = EMPTY;
|
||||
let (rank_dst, file_dst) = bitboard_to_coords(bitboard);
|
||||
|
||||
@@ -194,7 +193,7 @@ pub fn rook_attacks_on_the_fly(bitboard: Bitboard, blocker: Bitboard) -> Bitboar
|
||||
attacks
|
||||
}
|
||||
|
||||
pub fn set_occupancy(idx: u64, relevant_bits: usize, mut attack_mask: Bitboard) -> Bitboard {
|
||||
fn set_occupancy(idx: u64, relevant_bits: usize, mut attack_mask: Bitboard) -> Bitboard {
|
||||
let mut occupancy = EMPTY;
|
||||
|
||||
for bit in 0..relevant_bits {
|
||||
@@ -208,6 +207,7 @@ pub fn set_occupancy(idx: u64, relevant_bits: usize, mut attack_mask: Bitboard)
|
||||
occupancy
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fetch_pawn_attacks(square: usize, color: Color) -> Bitboard {
|
||||
match color {
|
||||
Color::White => PAWN_ATTACKS[square][0],
|
||||
@@ -215,16 +215,19 @@ pub fn fetch_pawn_attacks(square: usize, color: Color) -> Bitboard {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fetch_knight_attacks(square: usize) -> Bitboard {
|
||||
KNIGHT_ATTACKS[square]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fetch_king_attacks(square: usize) -> Bitboard {
|
||||
KING_ATTACKS[square]
|
||||
}
|
||||
|
||||
use crate::movegen::magic_bitboards::{BISHOP_MAGIC, ROOK_MAGIC};
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fetch_bishop_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard {
|
||||
occupancy &= mask_bishop_attacks(square_to_bitboard_wrapping(square));
|
||||
occupancy = occupancy.wrapping_mul(BISHOP_MAGIC[square]);
|
||||
@@ -232,18 +235,20 @@ pub fn fetch_bishop_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard
|
||||
BISHOP_ATTACKS[square][occupancy as usize]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fetch_rook_attacks(mut occupancy: Bitboard, square: usize) -> Bitboard {
|
||||
occupancy &= mask_rook_attacks(square_to_bitboard_wrapping(square));
|
||||
occupancy = occupancy.wrapping_mul(ROOK_MAGIC[square]);
|
||||
occupancy >>= 64 - ROOK_RELEVANT_BITS[square];
|
||||
ROOK_ATTACKS[&square][&(occupancy as usize)]
|
||||
ROOK_ATTACKS[square][occupancy as usize]
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn fetch_queen_attacks(occupancy: Bitboard, square: usize) -> Bitboard {
|
||||
fetch_rook_attacks(occupancy, square) | fetch_bishop_attacks(occupancy, square)
|
||||
}
|
||||
|
||||
pub fn init_pawn_attacks() -> [[Bitboard; 2]; 64] {
|
||||
fn init_pawn_attacks() -> [[Bitboard; 2]; 64] {
|
||||
array::from_fn(|square| {
|
||||
[
|
||||
pawn_attacks(square_to_bitboard(square), Color::White),
|
||||
@@ -252,74 +257,68 @@ pub fn init_pawn_attacks() -> [[Bitboard; 2]; 64] {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn init_knight_attacks() -> [Bitboard; 64] {
|
||||
fn init_knight_attacks() -> [Bitboard; 64] {
|
||||
array::from_fn(|square| knight_attacks(square_to_bitboard(square)))
|
||||
}
|
||||
|
||||
pub fn init_king_attacks() -> [Bitboard; 64] {
|
||||
fn init_king_attacks() -> [Bitboard; 64] {
|
||||
array::from_fn(|square| king_attacks(square_to_bitboard(square)))
|
||||
}
|
||||
|
||||
pub fn init_bishop_attacks() -> Box<[[Bitboard; 512]; 64]> {
|
||||
fn init_bishop_attacks() -> Vec<Vec<Bitboard>> {
|
||||
let mut bishop_masks = [0; 64];
|
||||
let mut bishop_atks: Box<[[Bitboard; 512]; 64]> = Box::new([[0; 512]; 64]);
|
||||
let mut bishop_atks: Vec<Vec<Bitboard>> = Vec::with_capacity(64);
|
||||
|
||||
for square in 0..64 {
|
||||
bishop_masks[square] = mask_bishop_attacks(square_to_bitboard(square));
|
||||
let attack_mask = bishop_masks[square];
|
||||
let occupancy_indices = square_to_bitboard(BISHOP_RELEVANT_BITS[square]);
|
||||
let mut square_attacks = vec![0; occupancy_indices as usize];
|
||||
|
||||
for idx in 0..occupancy_indices {
|
||||
let occupancy = set_occupancy(idx, BISHOP_RELEVANT_BITS[square], attack_mask);
|
||||
let magic_idx = (occupancy.wrapping_mul(BISHOP_MAGIC[square])
|
||||
>> (64 - BISHOP_RELEVANT_BITS[square])) as usize;
|
||||
let magic_idx =
|
||||
occupancy.wrapping_mul(BISHOP_MAGIC[square]) >> (64 - BISHOP_RELEVANT_BITS[square]);
|
||||
|
||||
bishop_atks[square][magic_idx] =
|
||||
square_attacks[magic_idx as usize] =
|
||||
bishop_attacks_on_the_fly(square_to_bitboard(square), occupancy);
|
||||
}
|
||||
bishop_atks.push(square_attacks);
|
||||
}
|
||||
bishop_atks
|
||||
}
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[allow(clippy::large_stack_frames)]
|
||||
pub fn init_rook_attacks() -> HashMap<usize, HashMap<usize, Bitboard>> {
|
||||
fn init_rook_attacks() -> Vec<Vec<Bitboard>> {
|
||||
let mut rook_masks: Vec<Bitboard> = vec![0; 64];
|
||||
let mut rook_atks: HashMap<usize, HashMap<usize, Bitboard>> = HashMap::new();
|
||||
let mut rook_atks: Vec<Vec<Bitboard>> = Vec::with_capacity(64);
|
||||
|
||||
for square in 0..64 {
|
||||
rook_masks[square] = mask_rook_attacks(square_to_bitboard(square));
|
||||
let attack_mask = rook_masks[square];
|
||||
let occupancy_indices = square_to_bitboard(ROOK_RELEVANT_BITS[square]);
|
||||
|
||||
let mut square_map: HashMap<usize, Bitboard> = HashMap::new();
|
||||
let mut square_attacks = vec![0; occupancy_indices as usize];
|
||||
|
||||
for idx in 0..occupancy_indices {
|
||||
let occupancy = set_occupancy(idx, ROOK_RELEVANT_BITS[square], attack_mask);
|
||||
let magic_idx = (occupancy.wrapping_mul(ROOK_MAGIC[square])
|
||||
>> (64 - ROOK_RELEVANT_BITS[square])) as usize;
|
||||
let occupancy = set_occupancy(idx as u64, ROOK_RELEVANT_BITS[square], attack_mask);
|
||||
let magic_idx =
|
||||
occupancy.wrapping_mul(ROOK_MAGIC[square]) >> (64 - ROOK_RELEVANT_BITS[square]);
|
||||
|
||||
square_map.insert(
|
||||
magic_idx,
|
||||
rook_attacks_on_the_fly(square_to_bitboard(square), occupancy),
|
||||
);
|
||||
square_attacks[magic_idx as usize] =
|
||||
rook_attacks_on_the_fly(square_to_bitboard(square), occupancy);
|
||||
}
|
||||
|
||||
rook_atks.insert(square, square_map);
|
||||
rook_atks.push(square_attacks);
|
||||
}
|
||||
|
||||
rook_atks
|
||||
}
|
||||
|
||||
use std::{array, sync::LazyLock};
|
||||
|
||||
pub fn init_attacks() {
|
||||
init_pawn_attacks();
|
||||
init_knight_attacks();
|
||||
init_king_attacks();
|
||||
init_bishop_attacks();
|
||||
init_rook_attacks();
|
||||
let _ = &*PAWN_ATTACKS;
|
||||
let _ = &*KNIGHT_ATTACKS;
|
||||
let _ = &*KING_ATTACKS;
|
||||
let _ = &*BISHOP_ATTACKS;
|
||||
let _ = &*ROOK_ATTACKS;
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user