1
0
Fork 0
This commit is contained in:
Paul-Nicolas Madelaine 2025-10-26 21:04:34 +01:00
parent 149aa841c9
commit 68f068989d
3 changed files with 103 additions and 126 deletions

View file

@ -9,22 +9,23 @@ macro_rules! container {
#[allow(unused)]
impl<T> $b<T> {
#[inline]
pub fn new<F>(f: F) -> Self
pub const fn new(inner: [T; $n]) -> Self {
Self(inner)
}
#[inline]
pub fn with<F>(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<T>(pub(crate) [T; 6]);
#[allow(unused)]
impl<T> ByRole<T> {
#[inline]
pub fn new<F>(f: F) -> Self
pub const fn new(inner: [T; 6]) -> Self {
Self(inner)
}
#[inline]
pub fn with<F>(f: F) -> Self
where
F: FnMut(Role) -> T,
{
@ -527,13 +532,13 @@ impl<T> ByRole<T> {
}
#[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<Self> {
if index < 8 {
Some(unsafe { Self::transmute(index) })
} else {
None
}
}
#[inline]
const unsafe fn transmute(value: u8) -> Self {
debug_assert!(value < 8);

View file

@ -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<ByDirection<Bitboard>> = by_square!(
square,
ByDirection([Bitboard(0); 8]),
by_direction!(direction, {
ByDirection<Bitboard>,
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<ByDirection<Bitboard>> = by_square!(
})
);
const LINES: BySquare<BySquare<Bitboard>> = by_square!(a, BySquare([Bitboard(0); 64]), {
by_square!(b, Bitboard(0), {
const LINES: BySquare<BySquare<Bitboard>> = by_square!(a, BySquare<Bitboard>, {
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<BySquare<Bitboard>> = by_square!(a, BySquare([Bitboard(0);
})
});
const SEGMENTS: BySquare<BySquare<Bitboard>> = by_square!(a, BySquare([Bitboard(0); 64]), {
by_square!(b, Bitboard(0), {
const SEGMENTS: BySquare<BySquare<Bitboard>> = by_square!(a, BySquare<Bitboard>, {
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<Bitboard> = by_square!(sq, Bitboard(0), {
const KING_MOVES: BySquare<Bitboard> = 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<Bitboard> = by_square!(sq, Bitboard(0), {
Bitboard(res)
});
const KNIGHT_MOVES: BySquare<Bitboard> = by_square!(s, Bitboard(0), {
const KNIGHT_MOVES: BySquare<Bitboard> = 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<BySquare<Bitboard>> = {
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<BySquare<Bitboard>> = {
};
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<Magic>, BySquare<Magic>, 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 =

View file

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