misc
This commit is contained in:
parent
faccfbc1c5
commit
a6a00fc819
3 changed files with 97 additions and 94 deletions
26
src/board.rs
26
src/board.rs
|
|
@ -194,7 +194,7 @@ impl Rank {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mirror(self) -> Self {
|
pub fn mirror(self) -> Self {
|
||||||
unsafe { Self::transmute(7_u8.unchecked_sub(self as u8)) }
|
unsafe { Self::transmute(!(self as u8)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -263,7 +263,7 @@ impl Square {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(file: File, rank: Rank) -> Self {
|
pub fn new(file: File, rank: Rank) -> Self {
|
||||||
unsafe { Self::transmute(((rank as u8) << 3) + file as u8) }
|
unsafe { Self::transmute(((rank as u8) << 3) | file as u8) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -278,7 +278,8 @@ impl Square {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn mirror(self) -> Self {
|
pub fn mirror(self) -> Self {
|
||||||
Self::new(self.file(), self.rank().mirror())
|
let sq = self as u8;
|
||||||
|
unsafe { Self::transmute(sq & 0b000111 | (!sq & 0b111000)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -389,18 +390,19 @@ impl std::str::FromStr for Square {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
#[allow(unused)]
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
#[rustfmt::skip]
|
|
||||||
pub(crate) enum OptionSquare {
|
pub(crate) enum OptionSquare {
|
||||||
_A1, _B1, _C1, _D1, _E1, _F1, _G1, _H1,
|
A1, B1, C1, D1, E1, F1, G1, H1,
|
||||||
_A2, _B2, _C2, _D2, _E2, _F2, _G2, _H2,
|
A2, B2, C2, D2, E2, F2, G2, H2,
|
||||||
_A3, _B3, _C3, _D3, _E3, _F3, _G3, _H3,
|
A3, B3, C3, D3, E3, F3, G3, H3,
|
||||||
_A4, _B4, _C4, _D4, _E4, _F4, _G4, _H4,
|
A4, B4, C4, D4, E4, F4, G4, H4,
|
||||||
_A5, _B5, _C5, _D5, _E5, _F5, _G5, _H5,
|
A5, B5, C5, D5, E5, F5, G5, H5,
|
||||||
_A6, _B6, _C6, _D6, _E6, _F6, _G6, _H6,
|
A6, B6, C6, D6, E6, F6, G6, H6,
|
||||||
_A7, _B7, _C7, _D7, _E7, _F7, _G7, _H7,
|
A7, B7, C7, D7, E7, F7, G7, H7,
|
||||||
_A8, _B8, _C8, _D8, _E8, _F8, _G8, _H8,
|
A8, B8, C8, D8, E8, F8, G8, H8,
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
155
src/position.rs
155
src/position.rs
|
|
@ -62,14 +62,6 @@ pub struct Position {
|
||||||
|
|
||||||
const MAX_LEGAL_MOVES: usize = 218;
|
const MAX_LEGAL_MOVES: usize = 218;
|
||||||
|
|
||||||
impl std::fmt::Debug for Position {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
|
||||||
f.debug_tuple("Position")
|
|
||||||
.field(&self.as_setup().to_string())
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Position {
|
impl Position {
|
||||||
/// Returns the initial position of a chess game.
|
/// Returns the initial position of a chess game.
|
||||||
///
|
///
|
||||||
|
|
@ -484,6 +476,14 @@ impl Position {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for Position {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||||
|
f.debug_tuple("Position")
|
||||||
|
.field(&self.as_setup().to_string())
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A legal move.
|
/// A legal move.
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
pub struct Move<'l> {
|
pub struct Move<'l> {
|
||||||
|
|
@ -657,7 +657,7 @@ impl<'l> Move<'l> {
|
||||||
},
|
},
|
||||||
suffix: {
|
suffix: {
|
||||||
let pos = self.make();
|
let pos = self.make();
|
||||||
let mut visitor = MateCollector::new();
|
let mut visitor = MateVisitorImpl::new();
|
||||||
pos.generate_moves(&mut visitor);
|
pos.generate_moves(&mut visitor);
|
||||||
visitor.is_check.then(|| match visitor.is_mate {
|
visitor.is_check.then(|| match visitor.is_mate {
|
||||||
true => SanSuffix::Checkmate,
|
true => SanSuffix::Checkmate,
|
||||||
|
|
@ -976,11 +976,6 @@ impl Position {
|
||||||
| d.knight(king_square) & theirs.knight()
|
| d.knight(king_square) & theirs.knight()
|
||||||
| x & theirs.bishop()
|
| x & theirs.bishop()
|
||||||
| y & theirs.rook();
|
| y & theirs.rook();
|
||||||
let blockers_x_ray = blockers & !(x | y);
|
|
||||||
let pinned = (d.bishop(king_square, blockers_x_ray) & theirs.bishop()
|
|
||||||
| d.rook(king_square, blockers_x_ray) & theirs.rook())
|
|
||||||
.map(|sq| d.segment(king_square, sq))
|
|
||||||
.reduce_or();
|
|
||||||
|
|
||||||
if visitor.roles(Role::King) && global_mask_from.contains(king_square) {
|
if visitor.roles(Role::King) && global_mask_from.contains(king_square) {
|
||||||
let attacked = {
|
let attacked = {
|
||||||
|
|
@ -1058,6 +1053,12 @@ impl Position {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let blockers_x_ray = blockers & !(x | y);
|
||||||
|
let pinned = (d.bishop(king_square, blockers_x_ray) & theirs.bishop()
|
||||||
|
| d.rook(king_square, blockers_x_ray) & theirs.rook())
|
||||||
|
.map(|sq| d.segment(king_square, sq))
|
||||||
|
.reduce_or();
|
||||||
|
|
||||||
let checker = checkers.first();
|
let checker = checkers.first();
|
||||||
let block_check = checker
|
let block_check = checker
|
||||||
.map(|checker| d.segment(king_square, checker))
|
.map(|checker| d.segment(king_square, checker))
|
||||||
|
|
@ -1091,7 +1092,7 @@ impl Position {
|
||||||
to,
|
to,
|
||||||
role: Role::Pawn,
|
role: Role::Pawn,
|
||||||
}));
|
}));
|
||||||
visitor.moves(WithPromotion::new((targets & promotion).map(|to| {
|
visitor.moves(MoveAndPromote::new((targets & promotion).map(|to| {
|
||||||
RawMove {
|
RawMove {
|
||||||
kind: MoveType::PawnAdvancePromotion,
|
kind: MoveType::PawnAdvancePromotion,
|
||||||
from: unsafe { to.trans_unchecked(!forward) },
|
from: unsafe { to.trans_unchecked(!forward) },
|
||||||
|
|
@ -1113,7 +1114,7 @@ impl Position {
|
||||||
to,
|
to,
|
||||||
role: Role::Pawn,
|
role: Role::Pawn,
|
||||||
}));
|
}));
|
||||||
visitor.moves(WithPromotion::new((targets & promotion).map(|to| {
|
visitor.moves(MoveAndPromote::new((targets & promotion).map(|to| {
|
||||||
RawMove {
|
RawMove {
|
||||||
kind: MoveType::PawnAttackPromotion,
|
kind: MoveType::PawnAttackPromotion,
|
||||||
from: unsafe { to.trans_unchecked(!kside) },
|
from: unsafe { to.trans_unchecked(!kside) },
|
||||||
|
|
@ -1135,7 +1136,7 @@ impl Position {
|
||||||
to,
|
to,
|
||||||
role: Role::Pawn,
|
role: Role::Pawn,
|
||||||
}));
|
}));
|
||||||
visitor.moves(WithPromotion::new((targets & promotion).map(|to| {
|
visitor.moves(MoveAndPromote::new((targets & promotion).map(|to| {
|
||||||
RawMove {
|
RawMove {
|
||||||
kind: MoveType::PawnAttackPromotion,
|
kind: MoveType::PawnAttackPromotion,
|
||||||
from: unsafe { to.trans_unchecked(!qside) },
|
from: unsafe { to.trans_unchecked(!qside) },
|
||||||
|
|
@ -1295,63 +1296,6 @@ impl Position {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WithPromotion<I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator> {
|
|
||||||
inner: I,
|
|
||||||
cur: std::mem::MaybeUninit<RawMove>,
|
|
||||||
role: Role,
|
|
||||||
}
|
|
||||||
impl<I> WithPromotion<I>
|
|
||||||
where
|
|
||||||
I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn new(inner: I) -> Self {
|
|
||||||
Self {
|
|
||||||
inner,
|
|
||||||
cur: std::mem::MaybeUninit::uninit(),
|
|
||||||
role: Role::King,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<I> Iterator for WithPromotion<I>
|
|
||||||
where
|
|
||||||
I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator,
|
|
||||||
{
|
|
||||||
type Item = RawMove;
|
|
||||||
#[inline]
|
|
||||||
fn next(&mut self) -> Option<RawMove> {
|
|
||||||
if self.role == Role::King {
|
|
||||||
self.cur.write(self.inner.next()?);
|
|
||||||
self.role = Role::Knight;
|
|
||||||
}
|
|
||||||
let raw = unsafe { self.cur.assume_init() };
|
|
||||||
let res = RawMove {
|
|
||||||
role: self.role,
|
|
||||||
..raw
|
|
||||||
};
|
|
||||||
self.role = unsafe { Role::transmute((self.role as u8).unchecked_add(1)) };
|
|
||||||
Some(res)
|
|
||||||
}
|
|
||||||
#[inline]
|
|
||||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
|
||||||
let len = self.len();
|
|
||||||
(len, Some(len))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<I> FusedIterator for WithPromotion<I> where
|
|
||||||
I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator
|
|
||||||
{
|
|
||||||
}
|
|
||||||
impl<I> ExactSizeIterator for WithPromotion<I>
|
|
||||||
where
|
|
||||||
I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator,
|
|
||||||
{
|
|
||||||
#[inline]
|
|
||||||
fn len(&self) -> usize {
|
|
||||||
unsafe { self.inner.len().unchecked_mul(4) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn aux_play_normal(setup: &mut Setup, role: Role, from: Square, target: Square) {
|
fn aux_play_normal(setup: &mut Setup, role: Role, from: Square, target: Square) {
|
||||||
let from = from.bitboard();
|
let from = from.bitboard();
|
||||||
|
|
@ -1458,11 +1402,11 @@ fn aux_play_castle(setup: &mut Setup, side: CastlingSide) {
|
||||||
setup.castling_rights.unset(setup.turn, CastlingSide::Long);
|
setup.castling_rights.unset(setup.turn, CastlingSide::Long);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MateCollector {
|
struct MateVisitorImpl {
|
||||||
is_check: bool,
|
is_check: bool,
|
||||||
is_mate: bool,
|
is_mate: bool,
|
||||||
}
|
}
|
||||||
impl MateCollector {
|
impl MateVisitorImpl {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -1471,7 +1415,7 @@ impl MateCollector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Visitor for MateCollector {
|
impl Visitor for MateVisitorImpl {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn is_check(&mut self) {
|
fn is_check(&mut self) {
|
||||||
self.is_check = true;
|
self.is_check = true;
|
||||||
|
|
@ -1486,3 +1430,60 @@ impl Visitor for MateCollector {
|
||||||
self.is_mate &= iter.len() == 0;
|
self.is_mate &= iter.len() == 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct MoveAndPromote<I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator> {
|
||||||
|
inner: I,
|
||||||
|
cur: std::mem::MaybeUninit<RawMove>,
|
||||||
|
role: Role,
|
||||||
|
}
|
||||||
|
impl<I> MoveAndPromote<I>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn new(inner: I) -> Self {
|
||||||
|
Self {
|
||||||
|
inner,
|
||||||
|
cur: std::mem::MaybeUninit::uninit(),
|
||||||
|
role: Role::King,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<I> Iterator for MoveAndPromote<I>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator,
|
||||||
|
{
|
||||||
|
type Item = RawMove;
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<RawMove> {
|
||||||
|
if self.role == Role::King {
|
||||||
|
self.cur.write(self.inner.next()?);
|
||||||
|
self.role = Role::Knight;
|
||||||
|
}
|
||||||
|
let raw = unsafe { self.cur.assume_init() };
|
||||||
|
let res = RawMove {
|
||||||
|
role: self.role,
|
||||||
|
..raw
|
||||||
|
};
|
||||||
|
self.role = unsafe { Role::transmute((self.role as u8).unchecked_add(1)) };
|
||||||
|
Some(res)
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||||
|
let len = self.len();
|
||||||
|
(len, Some(len))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<I> FusedIterator for MoveAndPromote<I> where
|
||||||
|
I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator
|
||||||
|
{
|
||||||
|
}
|
||||||
|
impl<I> ExactSizeIterator for MoveAndPromote<I>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = RawMove> + ExactSizeIterator + FusedIterator,
|
||||||
|
{
|
||||||
|
#[inline]
|
||||||
|
fn len(&self) -> usize {
|
||||||
|
unsafe { self.inner.len().unchecked_mul(4) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
10
src/setup.rs
10
src/setup.rs
|
|
@ -405,12 +405,12 @@ impl Setup {
|
||||||
};
|
};
|
||||||
ByRole::new(|kind| {
|
ByRole::new(|kind| {
|
||||||
mask & match kind {
|
mask & match kind {
|
||||||
Role::King => k,
|
|
||||||
Role::Queen => q,
|
|
||||||
Role::Bishop => b,
|
|
||||||
Role::Knight => n,
|
|
||||||
Role::Rook => r,
|
|
||||||
Role::Pawn => p,
|
Role::Pawn => p,
|
||||||
|
Role::Knight => n,
|
||||||
|
Role::Bishop => b,
|
||||||
|
Role::Rook => r,
|
||||||
|
Role::Queen => q,
|
||||||
|
Role::King => k,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue