vocabulary update
This commit is contained in:
parent
d17fae4fce
commit
5d1fa02280
3 changed files with 133 additions and 84 deletions
180
src/board.rs
180
src/board.rs
|
|
@ -3,28 +3,29 @@
|
|||
use crate::bitboard::*;
|
||||
|
||||
macro_rules! container {
|
||||
($a:ident, $b:ident, $n:literal) => {
|
||||
($v:vis, $a:ident, $b:ident, $n:literal) => {
|
||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub(crate) struct $b<T>(pub(crate) [T; $n]);
|
||||
$v struct $b<T>(pub(crate) [T; $n]);
|
||||
#[allow(unused)]
|
||||
impl<T> $b<T> {
|
||||
#[inline]
|
||||
pub fn new<F>(f: F) -> Self
|
||||
pub const fn new(values: [T; $n]) -> Self {
|
||||
Self(values)
|
||||
}
|
||||
#[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]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -38,11 +39,11 @@ pub enum Color {
|
|||
Black,
|
||||
}
|
||||
|
||||
container!(Color, ByColor, 2);
|
||||
container!(pub, Color, ByColor, 2);
|
||||
|
||||
impl Color {
|
||||
#[inline]
|
||||
pub fn all() -> [Self; 2] {
|
||||
pub const fn all() -> [Self; 2] {
|
||||
[Self::White, Self::Black]
|
||||
}
|
||||
|
||||
|
|
@ -96,11 +97,11 @@ pub enum File {
|
|||
H,
|
||||
}
|
||||
|
||||
container!(File, ByFile, 8);
|
||||
container!(pub(crate), File, ByFile, 8);
|
||||
|
||||
impl File {
|
||||
#[inline]
|
||||
pub fn all() -> [Self; 8] {
|
||||
pub const fn all() -> [Self; 8] {
|
||||
[
|
||||
Self::A,
|
||||
Self::B,
|
||||
|
|
@ -114,37 +115,55 @@ impl File {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_char(self) -> char {
|
||||
self.to_ascii() as char
|
||||
pub const fn new(index: u8) -> Option<Self> {
|
||||
if index < 8 {
|
||||
Some(unsafe { Self::new_unchecked(index) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_char(file: char) -> Option<Self> {
|
||||
u8::try_from(file).ok().and_then(Self::from_ascii)
|
||||
pub const unsafe fn new_unchecked(index: u8) -> Self {
|
||||
debug_assert!(index < 8);
|
||||
std::mem::transmute(index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn to_ascii(self) -> u8 {
|
||||
pub const fn to_ascii(self) -> u8 {
|
||||
self as u8 + b'a'
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn from_ascii(c: u8) -> Option<Self> {
|
||||
(c <= b'h')
|
||||
.then(|| c.checked_sub(b'a').map(|i| unsafe { Self::transmute(i) }))
|
||||
.flatten()
|
||||
pub const fn from_ascii(c: u8) -> Option<Self> {
|
||||
if c <= b'h' {
|
||||
match c.checked_sub(b'a') {
|
||||
Some(i) => Some(unsafe { Self::new_unchecked(i) }),
|
||||
None => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn to_char(self) -> char {
|
||||
self.to_ascii() as char
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn from_char(file: char) -> Option<Self> {
|
||||
if file as u32 <= 255 {
|
||||
Self::from_ascii(file as u8)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) const fn bitboard(self) -> Bitboard {
|
||||
Bitboard(0x0101010101010101 << (self as u8))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) const unsafe fn transmute(value: u8) -> Self {
|
||||
debug_assert!(value < 8);
|
||||
std::mem::transmute(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for File {
|
||||
|
|
@ -168,11 +187,11 @@ pub enum Rank {
|
|||
Eighth,
|
||||
}
|
||||
|
||||
container!(Rank, ByRank, 8);
|
||||
container!(pub(crate), Rank, ByRank, 8);
|
||||
|
||||
impl Rank {
|
||||
#[inline]
|
||||
pub fn all() -> [Self; 8] {
|
||||
pub const fn all() -> [Self; 8] {
|
||||
[
|
||||
Self::First,
|
||||
Self::Second,
|
||||
|
|
@ -186,42 +205,60 @@ impl Rank {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn to_char(self) -> char {
|
||||
self.to_ascii() as char
|
||||
pub const fn new(index: u8) -> Option<Self> {
|
||||
if index < 8 {
|
||||
Some(unsafe { Self::new_unchecked(index) })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_char(rank: char) -> Option<Self> {
|
||||
u8::try_from(rank).ok().and_then(Self::from_ascii)
|
||||
pub const unsafe fn new_unchecked(index: u8) -> Self {
|
||||
debug_assert!(index < 8);
|
||||
std::mem::transmute(index)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mirror(self) -> Self {
|
||||
unsafe { Self::transmute(!(self as u8)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn to_ascii(self) -> u8 {
|
||||
pub const fn to_ascii(self) -> u8 {
|
||||
self as u8 + b'1'
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn from_ascii(c: u8) -> Option<Self> {
|
||||
(c <= b'8')
|
||||
.then(|| c.checked_sub(b'1').map(|i| unsafe { Self::transmute(i) }))
|
||||
.flatten()
|
||||
pub const fn from_ascii(c: u8) -> Option<Self> {
|
||||
if c <= b'8' {
|
||||
match c.checked_sub(b'1') {
|
||||
Some(i) => Some(unsafe { Self::new_unchecked(i) }),
|
||||
None => None,
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn to_char(self) -> char {
|
||||
self.to_ascii() as char
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn from_char(rank: char) -> Option<Self> {
|
||||
if rank as u32 <= 255 {
|
||||
Self::from_ascii(rank as u8)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn mirror(self) -> Self {
|
||||
unsafe { Self::new_unchecked(!(self as u8)) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) const fn bitboard(self) -> Bitboard {
|
||||
Bitboard(0xFF << ((self as u64) << 3))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) const unsafe fn transmute(value: u8) -> Self {
|
||||
debug_assert!(value < 8);
|
||||
std::mem::transmute(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Rank {
|
||||
|
|
@ -246,12 +283,12 @@ pub enum Square{
|
|||
A8, B8, C8, D8, E8, F8, G8, H8,
|
||||
}
|
||||
|
||||
container!(Square, BySquare, 64);
|
||||
container!(pub, Square, BySquare, 64);
|
||||
|
||||
impl Square {
|
||||
#[inline]
|
||||
#[rustfmt::skip]
|
||||
pub fn all() -> [Self; 64] {
|
||||
pub const fn all() -> [Self; 64] {
|
||||
[
|
||||
Self::A1, Self::B1, Self::C1, Self::D1, Self::E1, Self::F1, Self::G1, Self::H1,
|
||||
Self::A2, Self::B2, Self::C2, Self::D2, Self::E2, Self::F2, Self::G2, Self::H2,
|
||||
|
|
@ -282,22 +319,22 @@ impl Square {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn from_coords(file: File, rank: Rank) -> Self {
|
||||
pub const fn from_coords(file: File, rank: Rank) -> Self {
|
||||
unsafe { Self::new_unchecked(((rank as u8) << 3) | file as u8) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn file(self) -> File {
|
||||
unsafe { File::transmute((self as u8) & 7) }
|
||||
unsafe { File::new_unchecked((self as u8) & 7) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn rank(self) -> Rank {
|
||||
unsafe { Rank::transmute((self as u8) >> 3) }
|
||||
unsafe { Rank::new_unchecked((self as u8) >> 3) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn mirror(self) -> Self {
|
||||
pub const fn mirror(self) -> Self {
|
||||
let sq = self as u8;
|
||||
unsafe { Self::new_unchecked(sq & 0b000111 | (!sq & 0b111000)) }
|
||||
}
|
||||
|
|
@ -465,7 +502,7 @@ pub enum Role {
|
|||
|
||||
impl Role {
|
||||
#[inline]
|
||||
pub fn all() -> [Self; 6] {
|
||||
pub const fn all() -> [Self; 6] {
|
||||
[
|
||||
Self::Pawn,
|
||||
Self::Knight,
|
||||
|
|
@ -521,11 +558,11 @@ impl Role {
|
|||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub(crate) struct ByRole<T>(pub(crate) [T; 6]);
|
||||
pub struct ByRole<T>(pub(crate) [T; 6]);
|
||||
#[allow(unused)]
|
||||
impl<T> ByRole<T> {
|
||||
#[inline]
|
||||
pub fn new<F>(f: F) -> Self
|
||||
pub fn with<F>(f: F) -> Self
|
||||
where
|
||||
F: FnMut(Role) -> T,
|
||||
{
|
||||
|
|
@ -533,13 +570,22 @@ 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 new(values: [T; 6]) -> Self {
|
||||
Self(values)
|
||||
}
|
||||
|
||||
#[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(&self, role: Role) -> &T {
|
||||
let i = unsafe { (role as usize).unchecked_sub(1) };
|
||||
unsafe { std::hint::assert_unchecked(i < 6) };
|
||||
&self.0[i]
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub const fn get_mut(&mut self, role: Role) -> &mut T {
|
||||
let i = unsafe { (role as usize).unchecked_sub(1) };
|
||||
unsafe { std::hint::assert_unchecked(i < 6) };
|
||||
&mut self.0[i]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -574,7 +620,7 @@ where
|
|||
}
|
||||
|
||||
/// A chess piece (i.e. its [`Role`] and [`Color`]).
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct Piece {
|
||||
pub role: Role,
|
||||
pub color: Color,
|
||||
|
|
@ -593,7 +639,7 @@ pub(crate) enum Direction {
|
|||
West,
|
||||
}
|
||||
|
||||
container!(Direction, ByDirection, 8);
|
||||
container!(pub(crate), Direction, ByDirection, 8);
|
||||
|
||||
impl Direction {
|
||||
#[inline]
|
||||
|
|
@ -644,7 +690,7 @@ pub enum CastlingSide {
|
|||
Long,
|
||||
}
|
||||
|
||||
container!(CastlingSide, ByCastlingSide, 2);
|
||||
container!(pub(crate), CastlingSide, ByCastlingSide, 2);
|
||||
|
||||
impl CastlingSide {
|
||||
#[inline]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue