WIP
This commit is contained in:
parent
d5cdf273c8
commit
091cc99cb3
42 changed files with 805 additions and 1662 deletions
|
@ -1,6 +1,6 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use crate::{errors::TryFromCharError, try_from_string};
|
||||
use crate::{errors::TryFromCharError, try_from_string, Direction};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, Eq, Hash, PartialEq)]
|
||||
|
@ -21,6 +21,7 @@ impl Color {
|
|||
Color::ALL.iter()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn into_iter() -> std::array::IntoIter<Color, { Self::NUM }> {
|
||||
Color::ALL.into_iter()
|
||||
}
|
||||
|
@ -33,6 +34,20 @@ impl Color {
|
|||
Color::Black => Color::White,
|
||||
}
|
||||
}
|
||||
|
||||
/// "Forward" direction of pawn pushes for this color.
|
||||
#[must_use]
|
||||
pub fn push_direction(&self) -> Direction {
|
||||
match self {
|
||||
Color::White => Direction::North,
|
||||
Color::Black => Direction::South,
|
||||
}
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub const fn next(&self) -> Color {
|
||||
Self::ALL[((*self as usize) + 1) % Self::NUM]
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for Color {
|
||||
|
|
|
@ -217,6 +217,43 @@ coordinate_enum!(Square, [
|
|||
A8, B8, C8, D8, E8, F8, G8, H8
|
||||
]);
|
||||
|
||||
/// Generate an enum that maps its values to variants of [Square].
|
||||
macro_rules! to_square_enum {
|
||||
($vis:vis $name:ident { $($variant:ident)* }) => {
|
||||
#[repr(u8)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
$vis enum $name {
|
||||
$($variant = Square::$variant as u8,)*
|
||||
}
|
||||
|
||||
impl From<$name> for Square {
|
||||
fn from(value: $name) -> Self {
|
||||
unsafe { Square::from_index_unchecked(value as u8) }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
to_square_enum!(
|
||||
pub EnPassantTargetSquare {
|
||||
A3 B3 C3 D3 E3 F3 G3 H3
|
||||
A6 B6 C6 D6 E6 F6 G6 H6
|
||||
}
|
||||
);
|
||||
|
||||
// impl TryFrom<Square> for EnPassantTargetSquare {
|
||||
// type Error = ();
|
||||
|
||||
// fn try_from(value: Square) -> Result<Self, Self::Error> {
|
||||
// let square = Self::ALL[value as usize];
|
||||
// if square as usize == value as usize {
|
||||
// Ok(square)
|
||||
// } else {
|
||||
// Err(())
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
impl Square {
|
||||
/// # Safety
|
||||
///
|
||||
|
@ -240,20 +277,24 @@ impl Square {
|
|||
s.parse()
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub fn file(self) -> File {
|
||||
unsafe { File::new_unchecked((self as u8) & 0b000_00111) }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
#[inline]
|
||||
pub fn rank(self) -> Rank {
|
||||
unsafe { Rank::new_unchecked((self as u8) >> 3) }
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn file_rank(&self) -> (File, Rank) {
|
||||
(self.file(), self.rank())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn neighbor(self, direction: Direction) -> Option<Square> {
|
||||
let index: u8 = self as u8;
|
||||
let dir: i8 = direction.to_offset();
|
||||
|
@ -347,10 +388,9 @@ impl From<File> for char {
|
|||
}
|
||||
}
|
||||
|
||||
impl Into<char> for Rank {
|
||||
fn into(self) -> char {
|
||||
let value: u8 = self.into();
|
||||
(value + b'1') as char
|
||||
impl From<Rank> for char {
|
||||
fn from(value: Rank) -> Self {
|
||||
Self::from(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,34 @@
|
|||
use crate::{errors::TryFromCharError, try_from_string, Color, Square};
|
||||
use std::{array, fmt, slice};
|
||||
|
||||
trait _Shape {
|
||||
fn symbol(&self) -> char;
|
||||
fn index(&self) -> usize;
|
||||
}
|
||||
|
||||
macro_rules! shape {
|
||||
($name:ident, $index:expr, $symbol:expr) => {
|
||||
struct $name;
|
||||
|
||||
impl _Shape for $name {
|
||||
fn symbol(&self) -> char {
|
||||
$symbol
|
||||
}
|
||||
|
||||
fn index(&self) -> usize {
|
||||
$index
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
shape!(Pawn, 0, 'P');
|
||||
shape!(Knight, 1, 'K');
|
||||
shape!(Bishop, 2, 'B');
|
||||
shape!(Rook, 3, 'R');
|
||||
shape!(Queen, 4, 'Q');
|
||||
shape!(King, 5, 'K');
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub enum Shape {
|
||||
Pawn = 0,
|
||||
|
@ -94,8 +122,8 @@ impl fmt::Display for Shape {
|
|||
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct Piece {
|
||||
color: Color,
|
||||
shape: Shape,
|
||||
pub color: Color,
|
||||
pub shape: Shape,
|
||||
}
|
||||
|
||||
macro_rules! piece_constructor {
|
||||
|
@ -132,16 +160,6 @@ impl Piece {
|
|||
piece_constructor!(queen, Queen);
|
||||
piece_constructor!(king, King);
|
||||
|
||||
#[must_use]
|
||||
pub fn color(&self) -> Color {
|
||||
self.color
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn shape(&self) -> Shape {
|
||||
self.shape
|
||||
}
|
||||
|
||||
is_shape!(is_pawn, Pawn);
|
||||
is_shape!(is_knight, Knight);
|
||||
is_shape!(is_bishop, Bishop);
|
||||
|
@ -195,10 +213,11 @@ impl From<&PlacedPiece> for Piece {
|
|||
}
|
||||
}
|
||||
|
||||
#[deprecated]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
|
||||
pub struct PlacedPiece {
|
||||
piece: Piece,
|
||||
square: Square,
|
||||
pub piece: Piece,
|
||||
pub square: Square,
|
||||
}
|
||||
|
||||
macro_rules! is_shape {
|
||||
|
@ -223,27 +242,6 @@ impl PlacedPiece {
|
|||
self.piece
|
||||
}
|
||||
|
||||
/// The square the piece is on
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn square(&self) -> Square {
|
||||
self.square
|
||||
}
|
||||
|
||||
/// The piece's [Color]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn color(&self) -> Color {
|
||||
self.piece.color
|
||||
}
|
||||
|
||||
/// The piece's [Shape]
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn shape(&self) -> Shape {
|
||||
self.piece.shape
|
||||
}
|
||||
|
||||
is_shape!(is_pawn, Pawn);
|
||||
is_shape!(is_knight, Knight);
|
||||
is_shape!(is_bishop, Bishop);
|
||||
|
@ -254,7 +252,7 @@ impl PlacedPiece {
|
|||
#[must_use]
|
||||
pub fn is_kingside_rook(&self) -> bool {
|
||||
self.is_rook()
|
||||
&& match self.color() {
|
||||
&& match self.piece.color {
|
||||
Color::White => self.square == Square::H1,
|
||||
Color::Black => self.square == Square::H8,
|
||||
}
|
||||
|
@ -263,7 +261,7 @@ impl PlacedPiece {
|
|||
#[must_use]
|
||||
pub fn is_queenside_rook(&self) -> bool {
|
||||
self.is_rook()
|
||||
&& match self.color() {
|
||||
&& match self.piece.color {
|
||||
Color::White => self.square == Square::A1,
|
||||
Color::Black => self.square == Square::A8,
|
||||
}
|
||||
|
@ -294,6 +292,6 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn shape_into_char() {
|
||||
assert_eq!(<Shape as Into<char>>::into(Shape::Pawn) as char, 'P');
|
||||
assert_eq!(<Shape as Into<char>>::into(Shape::Pawn), 'P');
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue