Implement a whole new move crate

This commit is contained in:
Eryn Wells 2024-02-09 20:00:47 -08:00
parent 0bedf2aa9f
commit c55b7c4877
7 changed files with 512 additions and 148 deletions

View file

@ -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 {