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,72 +1,45 @@
|
|||
// Eryn Wells <eryn@erynwells.me>
|
||||
|
||||
use crate::castle::Castle;
|
||||
use chessfriend_core::{PlacedPiece, Shape, Square};
|
||||
use crate::{castle::Castle, defs::Kind};
|
||||
use chessfriend_core::{Rank, Shape, Square};
|
||||
use std::fmt;
|
||||
|
||||
#[repr(u16)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum PromotableShape {
|
||||
Knight = 0b00,
|
||||
Bishop = 0b01,
|
||||
Rook = 0b10,
|
||||
Queen = 0b11,
|
||||
}
|
||||
|
||||
#[repr(u16)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
enum Kind {
|
||||
Quiet = 0b00,
|
||||
DoublePush = 0b01,
|
||||
Castle(Castle),
|
||||
Capture(PlacedPiece) = 0b0100,
|
||||
EnPassantCapture(PlacedPiece) = 0b0101,
|
||||
Promotion(PromotableShape) = 0b1000,
|
||||
CapturePromotion(PlacedPiece, PromotableShape) = 0b1100,
|
||||
}
|
||||
|
||||
impl Kind {
|
||||
fn bits(&self) -> u16 {
|
||||
match self {
|
||||
Self::Promotion(shape) => self.discriminant() | *shape as u16,
|
||||
Self::CapturePromotion(_, shape) => self.discriminant() | *shape as u16,
|
||||
Self::Castle(castle) => *castle as u16,
|
||||
_ => self.discriminant(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Return the discriminant value. This implementation is copied from the Rust docs.
|
||||
/// See https://doc.rust-lang.org/std/mem/fn.discriminant.html
|
||||
fn discriminant(&self) -> u16 {
|
||||
unsafe { *<*const _>::from(self).cast::<u16>() }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Kind {
|
||||
fn default() -> Self {
|
||||
Self::Quiet
|
||||
}
|
||||
}
|
||||
|
||||
/// A single player's move. In chess parlance, this is a "ply".
|
||||
#[derive(Clone, Copy, Eq, Hash, PartialEq)]
|
||||
pub struct Move(pub(crate) u16);
|
||||
|
||||
impl Move {
|
||||
pub fn from_square(&self) -> Square {
|
||||
pub fn origin_square(&self) -> Square {
|
||||
((self.0 >> 4) & 0b111111).try_into().unwrap()
|
||||
}
|
||||
|
||||
pub fn to_square(&self) -> Square {
|
||||
pub fn target_square(&self) -> Square {
|
||||
(self.0 >> 10).try_into().unwrap()
|
||||
}
|
||||
|
||||
pub fn capture_square(&self) -> Option<Square> {
|
||||
if self.is_capture() {
|
||||
return Some(self.target_square());
|
||||
}
|
||||
|
||||
if self.is_en_passant() {
|
||||
let target_square = self.target_square();
|
||||
return Some(match target_square.rank() {
|
||||
Rank::THREE => Square::from_file_rank(target_square.file(), Rank::FOUR),
|
||||
Rank::SIX => Square::from_file_rank(target_square.file(), Rank::FIVE),
|
||||
_ => unreachable!(),
|
||||
});
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
pub fn is_quiet(&self) -> bool {
|
||||
self.flags() == Kind::Quiet.discriminant()
|
||||
self.flags() == Kind::Quiet as u16
|
||||
}
|
||||
|
||||
pub fn is_double_push(&self) -> bool {
|
||||
self.flags() == Kind::DoublePush.discriminant()
|
||||
self.flags() == Kind::DoublePush as u16
|
||||
}
|
||||
|
||||
pub fn is_castle(&self) -> bool {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue