From 68f068989db23942c30ec22aca6531ca865cf58a Mon Sep 17 00:00:00 2001 From: Paul-Nicolas Madelaine Date: Sun, 26 Oct 2025 21:04:34 +0100 Subject: [PATCH] wip --- src/board.rs | 40 +++++------ src/lookup.rs | 185 ++++++++++++++++++++++---------------------------- src/setup.rs | 4 +- 3 files changed, 103 insertions(+), 126 deletions(-) diff --git a/src/board.rs b/src/board.rs index 9833d61..606ccad 100644 --- a/src/board.rs +++ b/src/board.rs @@ -9,22 +9,23 @@ macro_rules! container { #[allow(unused)] impl $b { #[inline] - pub fn new(f: F) -> Self + pub const fn new(inner: [T; $n]) -> Self { + Self(inner) + } + #[inline] + pub fn with(f: F) -> Self where F: FnMut($a) -> T, { Self($a::all().map(f)) } #[inline] - pub fn get(&self, k: $a) -> &T { - unsafe { self.0.get_unchecked(k as usize) } + pub const fn get(&self, k: $a) -> &T { + &self.0[k as usize] } #[inline] - pub fn get_mut(&mut self, k: $a) -> &mut T { - unsafe { self.0.get_unchecked_mut(k as usize) } - } - pub(crate) const fn get_const(&self, k: $a) -> &T { - &self.0[k as usize] + pub const fn get_mut(&mut self, k: $a) -> &mut T { + &mut self.0[k as usize] } } }; @@ -519,7 +520,11 @@ pub(crate) struct ByRole(pub(crate) [T; 6]); #[allow(unused)] impl ByRole { #[inline] - pub fn new(f: F) -> Self + pub const fn new(inner: [T; 6]) -> Self { + Self(inner) + } + #[inline] + pub fn with(f: F) -> Self where F: FnMut(Role) -> T, { @@ -527,13 +532,13 @@ impl ByRole { } #[inline] - pub fn get(&self, kind: Role) -> &T { - unsafe { self.0.get_unchecked((kind as usize).unchecked_sub(1)) } + pub const fn get(&self, role: Role) -> &T { + &self.0[role as usize - 1] } #[inline] - pub fn get_mut(&mut self, kind: Role) -> &mut T { - unsafe { self.0.get_unchecked_mut((kind as usize).unchecked_sub(1)) } + pub const fn get_mut(&mut self, role: Role) -> &mut T { + &mut self.0[role as usize - 1] } } @@ -604,15 +609,6 @@ impl Direction { ] } - #[inline] - pub(crate) const fn from_index(index: u8) -> Option { - if index < 8 { - Some(unsafe { Self::transmute(index) }) - } else { - None - } - } - #[inline] const unsafe fn transmute(value: u8) -> Self { debug_assert!(value < 8); diff --git a/src/lookup.rs b/src/lookup.rs index aaabdf3..311b4be 100644 --- a/src/lookup.rs +++ b/src/lookup.rs @@ -2,6 +2,8 @@ use crate::bitboard::*; use crate::board::*; use crate::magics::*; +use std::mem::MaybeUninit; + macro_rules! loop_subsets { ($premask: ident, $subset: ident, $e: expr) => {{ let mut $subset: u64 = 0; @@ -16,8 +18,8 @@ macro_rules! loop_subsets { } macro_rules! by_color { - ($c: ident, $e: expr) => {{ - ByColor([ + ($c: ident, $e: expr) => { + ByColor::new([ { let $c = Color::White; $e @@ -27,21 +29,21 @@ macro_rules! by_color { $e }, ]) - }}; + }; } macro_rules! by_square { - ($sq: ident, $init: expr, $e: expr) => {{ - let mut res = [$init; 64]; - let mut $sq: u8 = 0; - while $sq < 64 { - res[$sq as usize] = { - let $sq = Square::from_index($sq).unwrap(); + ($s: ident, $t: ty, $e: expr) => {{ + let mut res = [MaybeUninit::uninit(); 64]; + let mut $s: u8 = 0; + while $s < 64 { + res[$s as usize].write({ + let $s = Square::from_index($s).unwrap(); $e - }; - $sq += 1; + }); + $s += 1; } - BySquare(res) + BySquare::new(unsafe { std::mem::transmute::<_, [$t;64]>(res) }) }}; } @@ -95,24 +97,19 @@ macro_rules! loop_all_directions { } macro_rules! by_direction { - ($d: ident, $e: expr) => {{ - let mut res = [Bitboard(0); 8]; - let mut $d: u8 = 0; - while $d < 8 { - res[$d as usize] = { - let $d = Direction::from_index($d).unwrap(); - $e - }; - $d += 1; - } - ByDirection(res) + ($d: ident, $t: ty, $e: expr) => {{ + let mut res = [MaybeUninit::uninit(); 8]; + loop_all_directions!($d, { + res[$d as u8 as usize].write($e); + }); + ByDirection(unsafe { std::mem::transmute::<_, [$t;8]>(res) }) }}; } const RAYS: BySquare> = by_square!( square, - ByDirection([Bitboard(0); 8]), - by_direction!(direction, { + ByDirection, + by_direction!(direction, Bitboard, { let mut square = square; let mut res = 0; while let Some(x) = square.trans(direction) { @@ -123,11 +120,11 @@ const RAYS: BySquare> = by_square!( }) ); -const LINES: BySquare> = by_square!(a, BySquare([Bitboard(0); 64]), { - by_square!(b, Bitboard(0), { +const LINES: BySquare> = by_square!(a, BySquare, { + by_square!(b, Bitboard, { let mut res = Bitboard(0); loop_all_directions!(d, { - let r = *RAYS.get_const(a).get_const(d); + let r = *RAYS.get(a).get(d); if r.contains(b) { res = r; } @@ -136,20 +133,20 @@ const LINES: BySquare> = by_square!(a, BySquare([Bitboard(0); }) }); -const SEGMENTS: BySquare> = by_square!(a, BySquare([Bitboard(0); 64]), { - by_square!(b, Bitboard(0), { +const SEGMENTS: BySquare> = by_square!(a, BySquare, { + by_square!(b, Bitboard, { let mut res = 0; loop_all_directions!(d, { - let r = *RAYS.get_const(a).get_const(d); + let r = *RAYS.get(a).get(d); if r.contains(b) { - res = r.0 & !RAYS.get_const(b).get_const(d).0; + res = r.0 & !RAYS.get(b).get(d).0; } }); Bitboard(res | b.bitboard().0) }) }); -const KING_MOVES: BySquare = by_square!(sq, Bitboard(0), { +const KING_MOVES: BySquare = by_square!(sq, Bitboard, { let mut res = 0; loop_all_directions!(d, { if let Some(x) = sq.trans(d) { @@ -159,7 +156,7 @@ const KING_MOVES: BySquare = by_square!(sq, Bitboard(0), { Bitboard(res) }); -const KNIGHT_MOVES: BySquare = by_square!(s, Bitboard(0), { +const KNIGHT_MOVES: BySquare = by_square!(s, Bitboard, { let mut res = Bitboard(0); if let Some(s) = s.trans(Direction::North) { if let Some(s) = s.trans(Direction::NorthEast) { @@ -202,7 +199,7 @@ const PAWN_ATTACKS: ByColor> = { Color::White => Direction::North, Color::Black => Direction::South, }; - by_square!(square, Bitboard(0), { + by_square!(square, Bitboard, { let mut res = Bitboard(0); if let Some(square) = square.trans(direction) { if let Some(s) = square.trans(Direction::East) { @@ -218,7 +215,7 @@ const PAWN_ATTACKS: ByColor> = { }; const fn blocked_ray(square: Square, direction: Direction, blockers: Bitboard) -> Bitboard { - let ray = *RAYS.get_const(square).get_const(direction); + let ray = *RAYS.get(square).get(direction); let blockers = Bitboard(blockers.0 & ray.0); let square = if (direction as u8) < 4 { Bitboard::first(&blockers) @@ -227,7 +224,7 @@ const fn blocked_ray(square: Square, direction: Direction, blockers: Bitboard) - }; match square { None => ray, - Some(square) => Bitboard(ray.0 & !RAYS.get_const(square).get_const(direction).0), + Some(square) => Bitboard(ray.0 & !RAYS.get(square).get(direction).0), } } @@ -259,7 +256,7 @@ pub(crate) fn pawn_attack(color: Color, square: Square) -> Bitboard { const fn bishop_premask(square: Square) -> Bitboard { let mut premask = 0; loop_bishop_directions!(direction, { - premask |= RAYS.get_const(square).get_const(direction).0; + premask |= RAYS.get(square).get(direction).0; }); premask &= !Rank::First.bitboard().0; premask &= !Rank::Eighth.bitboard().0; @@ -269,78 +266,62 @@ const fn bishop_premask(square: Square) -> Bitboard { } const fn rook_premask(square: Square) -> Bitboard { - let rays = RAYS.get_const(square); + let rays = RAYS.get(square); let mut premask = 0; - premask |= rays.get_const(Direction::East).0 & !File::H.bitboard().0; - premask |= rays.get_const(Direction::North).0 & !Rank::Eighth.bitboard().0; - premask |= rays.get_const(Direction::West).0 & !File::A.bitboard().0; - premask |= rays.get_const(Direction::South).0 & !Rank::First.bitboard().0; + premask |= rays.get(Direction::East).0 & !File::H.bitboard().0; + premask |= rays.get(Direction::North).0 & !Rank::Eighth.bitboard().0; + premask |= rays.get(Direction::West).0 & !File::A.bitboard().0; + premask |= rays.get(Direction::South).0 & !Rank::First.bitboard().0; Bitboard(premask) } const MAGICS: (BySquare, BySquare, usize) = { let mut len: usize = 0; ( - by_square!( - square, - Magic { - premask: Bitboard(0), - factor: 0, - offset: 0 - }, - { - let premask = bishop_premask(square).0; - let factor = bishop_factor(square); - let mut i = usize::MAX; - let mut j = 0; - loop_subsets!(premask, blockers, { - let cur = hash(BISHOP_SHR, factor, Bitboard(blockers | !premask)); - if cur < i { - i = cur; - } - if cur > j { - j = cur; - } - }); - let offset = len as isize - i as isize; - len += j - i + 1; - Magic { - premask: Bitboard(!premask), - factor, - offset, + by_square!(square, Magic, { + let premask = bishop_premask(square).0; + let factor = bishop_factor(square); + let mut i = usize::MAX; + let mut j = 0; + loop_subsets!(premask, blockers, { + let cur = hash(BISHOP_SHR, factor, Bitboard(blockers | !premask)); + if cur < i { + i = cur; } - } - ), - by_square!( - square, - Magic { - premask: Bitboard(0), - factor: 0, - offset: 0 - }, - { - let premask = rook_premask(square).0; - let factor = rook_factor(square); - let mut i = usize::MAX; - let mut j = 0; - loop_subsets!(premask, blockers, { - let cur = hash(ROOK_SHR, factor, Bitboard(blockers | !premask)); - if cur < i { - i = cur; - } - if cur > j { - j = cur; - } - }); - let offset = len as isize - i as isize; - len += j - i + 1; - Magic { - premask: Bitboard(!premask), - factor, - offset, + if cur > j { + j = cur; } + }); + let offset = len as isize - i as isize; + len += j - i + 1; + Magic { + premask: Bitboard(!premask), + factor, + offset, } - ), + }), + by_square!(square, Magic, { + let premask = rook_premask(square).0; + let factor = rook_factor(square); + let mut i = usize::MAX; + let mut j = 0; + loop_subsets!(premask, blockers, { + let cur = hash(ROOK_SHR, factor, Bitboard(blockers | !premask)); + if cur < i { + i = cur; + } + if cur > j { + j = cur; + } + }); + let offset = len as isize - i as isize; + len += j - i + 1; + Magic { + premask: Bitboard(!premask), + factor, + offset, + } + }), len, ) }; @@ -360,7 +341,7 @@ const MAGIC_TABLE: [Bitboard; MAGICS.2] = { premask, factor, offset, - } = *MAGICS.0.get_const(square); + } = *MAGICS.0.get(square); let premask = !premask.0; loop_subsets!(premask, blockers, { let index = (hash(BISHOP_SHR, factor, Bitboard(blockers | !premask)) as isize + offset) @@ -378,7 +359,7 @@ const MAGIC_TABLE: [Bitboard; MAGICS.2] = { premask, factor, offset, - } = *MAGICS.1.get_const(square); + } = *MAGICS.1.get(square); let premask = !premask.0; loop_subsets!(premask, blockers, { let index = diff --git a/src/setup.rs b/src/setup.rs index ac06172..9ae0e61 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -490,12 +490,12 @@ impl Setup { let n = n_b_k ^ b ^ k; let r = r_q_k ^ q ^ k; let p = p_b_q ^ b ^ q; - ByColor::new(|color| { + ByColor::with(|color| { let mask = match color { Color::White => w, Color::Black => !w, }; - ByRole::new(|kind| { + ByRole::with(|kind| { mask & match kind { Role::Pawn => p, Role::Knight => n,