wip
This commit is contained in:
parent
149aa841c9
commit
68f068989d
3 changed files with 103 additions and 126 deletions
40
src/board.rs
40
src/board.rs
|
|
@ -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);
|
||||
|
|
|
|||
185
src/lookup.rs
185
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<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 =
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue