Implement a whole new move crate
This commit is contained in:
parent
0bedf2aa9f
commit
c55b7c4877
7 changed files with 512 additions and 148 deletions
|
@ -1,9 +1,35 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use crate::{castle, Move};
|
||||
use chessfriend_core::{PlacedPiece, Square};
|
||||
use crate::{castle, defs::Kind, Move, PromotionShape};
|
||||
use chessfriend_core::{Color, File, PlacedPiece, Rank, Square};
|
||||
use std::result::Result as StdResult;
|
||||
|
||||
pub trait Style {}
|
||||
pub type Result = std::result::Result<Move, Error>;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum Error {
|
||||
MissingOriginSquare,
|
||||
MissingTargetSquare,
|
||||
MissingCaptureSquare,
|
||||
InvalidEnPassantSquare,
|
||||
}
|
||||
|
||||
pub trait Style {
|
||||
fn origin_square(&self) -> Option<Square> {
|
||||
None
|
||||
}
|
||||
|
||||
fn target_square(&self) -> Option<Square> {
|
||||
None
|
||||
}
|
||||
|
||||
fn into_move_bits(&self) -> StdResult<u16, Error> {
|
||||
let origin_square = self.origin_square().ok_or(Error::MissingOriginSquare)? as u16;
|
||||
let target_square = self.target_square().ok_or(Error::MissingTargetSquare)? as u16;
|
||||
|
||||
Ok((origin_square & 0b111111) << 4 | (target_square & 0b111111) << 10)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct Builder<S: Style> {
|
||||
|
@ -19,67 +45,241 @@ pub struct Push {
|
|||
to: Option<Square>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct DoublePush {
|
||||
from: Square,
|
||||
to: Square,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct Capture {
|
||||
push: Push,
|
||||
capture: Option<Square>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub struct EnPassantCapture {
|
||||
push: Push,
|
||||
capture: Option<Square>,
|
||||
}
|
||||
|
||||
pub struct Promotion<S> {
|
||||
style: S,
|
||||
promotion: PromotionShape,
|
||||
}
|
||||
|
||||
pub struct Castle {
|
||||
castle: castle::Castle,
|
||||
}
|
||||
|
||||
impl Style for Null {}
|
||||
impl Style for Push {}
|
||||
impl Style for Capture {}
|
||||
|
||||
impl Style for Push {
|
||||
fn origin_square(&self) -> Option<Square> {
|
||||
self.from
|
||||
}
|
||||
|
||||
fn target_square(&self) -> Option<Square> {
|
||||
self.to
|
||||
}
|
||||
}
|
||||
|
||||
impl Style for Capture {
|
||||
fn origin_square(&self) -> Option<Square> {
|
||||
self.push.from
|
||||
}
|
||||
|
||||
fn target_square(&self) -> Option<Square> {
|
||||
self.push.to
|
||||
}
|
||||
}
|
||||
|
||||
impl Style for Castle {}
|
||||
|
||||
impl Style for DoublePush {
|
||||
fn origin_square(&self) -> Option<Square> {
|
||||
Some(self.from)
|
||||
}
|
||||
|
||||
fn target_square(&self) -> Option<Square> {
|
||||
Some(self.to)
|
||||
}
|
||||
|
||||
fn into_move_bits(&self) -> StdResult<u16, Error> {
|
||||
Ok(Kind::DoublePush as u16
|
||||
| (self.from as u16 & 0b111111) << 4
|
||||
| (self.to as u16 & 0b111111) << 10)
|
||||
}
|
||||
}
|
||||
|
||||
impl Style for EnPassantCapture {
|
||||
fn origin_square(&self) -> Option<Square> {
|
||||
self.push.from
|
||||
}
|
||||
|
||||
fn target_square(&self) -> Option<Square> {
|
||||
self.push.to
|
||||
}
|
||||
|
||||
fn into_move_bits(&self) -> StdResult<u16, Error> {
|
||||
let origin_square = self.origin_square().ok_or(Error::MissingOriginSquare)? as u16;
|
||||
let target_square = self.target_square().ok_or(Error::MissingTargetSquare)? as u16;
|
||||
|
||||
Ok((origin_square & 0b111111) << 4 | (target_square & 0b111111) << 10)
|
||||
}
|
||||
}
|
||||
|
||||
impl Style for Promotion<Push> {
|
||||
fn origin_square(&self) -> Option<Square> {
|
||||
self.style.from
|
||||
}
|
||||
|
||||
fn target_square(&self) -> Option<Square> {
|
||||
self.style.to
|
||||
}
|
||||
}
|
||||
|
||||
impl Style for Promotion<Capture> {
|
||||
fn origin_square(&self) -> Option<Square> {
|
||||
self.style.push.from
|
||||
}
|
||||
|
||||
fn target_square(&self) -> Option<Square> {
|
||||
self.style.push.to
|
||||
}
|
||||
}
|
||||
|
||||
impl Promotion<Push> {
|
||||
fn into_move_bits(&self) -> StdResult<u16, Error> {
|
||||
let origin_square = self
|
||||
.style
|
||||
.origin_square()
|
||||
.ok_or(Error::MissingOriginSquare)? as u16;
|
||||
let target_square = self
|
||||
.style
|
||||
.target_square()
|
||||
.ok_or(Error::MissingTargetSquare)? as u16;
|
||||
|
||||
Ok(Kind::Promotion as u16
|
||||
| self.promotion as u16
|
||||
| (origin_square & 0b111111) << 4
|
||||
| (target_square & 0b111111) << 10)
|
||||
}
|
||||
}
|
||||
|
||||
impl Promotion<Capture> {
|
||||
fn into_move_bits(&self) -> StdResult<u16, Error> {
|
||||
let origin_square = self
|
||||
.style
|
||||
.origin_square()
|
||||
.ok_or(Error::MissingOriginSquare)? as u16;
|
||||
let target_square = self
|
||||
.style
|
||||
.target_square()
|
||||
.ok_or(Error::MissingTargetSquare)? as u16;
|
||||
|
||||
Ok(Kind::CapturePromotion as u16
|
||||
| self.promotion as u16
|
||||
| (origin_square & 0b111111) << 4
|
||||
| (target_square & 0b111111) << 10)
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<Null> {
|
||||
pub fn new() -> Self {
|
||||
Self { style: Null }
|
||||
}
|
||||
|
||||
pub fn piece(piece: &PlacedPiece) -> Builder<Push> {
|
||||
pub fn push(piece: &PlacedPiece, to: Square) -> Builder<Push> {
|
||||
Builder {
|
||||
style: Push {
|
||||
from: Some(piece.square()),
|
||||
to: None,
|
||||
to: Some(to),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn double_push(file: File, color: Color) -> Builder<DoublePush> {
|
||||
let (from, to) = match color {
|
||||
Color::White => (
|
||||
Square::from_file_rank(file, Rank::TWO),
|
||||
Square::from_file_rank(file, Rank::FOUR),
|
||||
),
|
||||
Color::Black => (
|
||||
Square::from_file_rank(file, Rank::SEVEN),
|
||||
Square::from_file_rank(file, Rank::FIVE),
|
||||
),
|
||||
};
|
||||
|
||||
Builder {
|
||||
style: DoublePush { from, to },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn castling(castle: castle::Castle) -> Builder<Castle> {
|
||||
Builder {
|
||||
style: Castle { castle },
|
||||
}
|
||||
}
|
||||
|
||||
pub fn capturing_on(piece: &PlacedPiece, to: Square) -> Builder<Capture> {
|
||||
Self::push(piece, to).capturing_on(to)
|
||||
}
|
||||
|
||||
pub fn capturing_piece(piece: &PlacedPiece, capturing: &PlacedPiece) -> Builder<Capture> {
|
||||
Self::push(piece, capturing.square()).capturing_piece(&capturing)
|
||||
}
|
||||
|
||||
pub fn from(self, square: Square) -> Builder<Push> {
|
||||
Builder {
|
||||
style: Push {
|
||||
from: Some(square),
|
||||
to: None,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(&self) -> Move {
|
||||
Move(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<Push> {
|
||||
pub fn from(mut self, square: Square) -> Self {
|
||||
pub fn from(&mut self, square: Square) -> &mut Self {
|
||||
self.style.from = Some(square);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn to(mut self, square: Square) -> Self {
|
||||
pub fn to(&mut self, square: Square) -> &mut Self {
|
||||
self.style.to = Some(square);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn capturing(self, square: Square) -> Builder<Capture> {
|
||||
pub fn capturing_on(self, square: Square) -> Builder<Capture> {
|
||||
let mut style = self.style;
|
||||
style.to = Some(square);
|
||||
|
||||
Builder {
|
||||
style: Capture {
|
||||
push: style,
|
||||
capture: Some(square),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn capturing_en_passant_on(self, square: Square) -> Builder<EnPassantCapture> {
|
||||
let mut style = self.style;
|
||||
style.to = Some(square);
|
||||
|
||||
Builder {
|
||||
style: EnPassantCapture {
|
||||
push: self.style,
|
||||
capture: Some(square),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn capturing_piece(self, piece: PlacedPiece) -> Builder<Capture> {
|
||||
pub fn capturing_piece(self, piece: &PlacedPiece) -> Builder<Capture> {
|
||||
Builder {
|
||||
style: Capture {
|
||||
push: self.style,
|
||||
|
@ -87,19 +287,73 @@ impl Builder<Push> {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn promoting_to(self, shape: PromotionShape) -> Builder<Promotion<Push>> {
|
||||
Builder {
|
||||
style: Promotion {
|
||||
style: self.style,
|
||||
promotion: shape,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(&self) -> Result {
|
||||
Ok(Move(Kind::Quiet as u16 | self.style.into_move_bits()?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<Castle> {
|
||||
fn bits(&self) -> u16 {
|
||||
let bits = match self.style.castle {
|
||||
castle::Castle::KingSide => Kind::KingSideCastle,
|
||||
castle::Castle::QueenSide => Kind::QueenSideCastle,
|
||||
};
|
||||
|
||||
bits as u16
|
||||
}
|
||||
|
||||
pub fn build(&self) -> Move {
|
||||
Move(self.style.into_bits())
|
||||
Move(self.bits())
|
||||
}
|
||||
}
|
||||
|
||||
impl Castle {
|
||||
fn into_bits(&self) -> u16 {
|
||||
match self.castle {
|
||||
castle::Castle::KingSide => 0b10,
|
||||
castle::Castle::QueenSide => 0b11,
|
||||
impl Builder<Capture> {
|
||||
pub fn promoting_to(self, shape: PromotionShape) -> Builder<Promotion<Capture>> {
|
||||
Builder {
|
||||
style: Promotion {
|
||||
style: self.style,
|
||||
promotion: shape,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build(&self) -> Result {
|
||||
Ok(Move(Kind::Capture as u16 | self.style.into_move_bits()?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<DoublePush> {
|
||||
pub fn build(&self) -> Result {
|
||||
Ok(Move(Kind::DoublePush as u16 | self.style.into_move_bits()?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<EnPassantCapture> {
|
||||
pub unsafe fn build_unchecked(&self) -> Result {
|
||||
Ok(Move(
|
||||
Kind::EnPassantCapture as u16 | self.style.into_move_bits()?,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<Promotion<Push>> {
|
||||
pub fn build(&self) -> Result {
|
||||
Ok(Move(self.style.into_move_bits()?))
|
||||
}
|
||||
}
|
||||
|
||||
impl Builder<Promotion<Capture>> {
|
||||
pub fn build(&self) -> Result {
|
||||
Ok(Move(self.style.into_move_bits()?))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue