Skip to content

Commit

Permalink
chore: debugging some castling / parsing issues
Browse files Browse the repository at this point in the history
  • Loading branch information
dannyhammer committed Oct 28, 2024
1 parent 0d61811 commit 6842b34
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
20 changes: 14 additions & 6 deletions chessie/src/moves.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ impl MoveKind {
}

// King moves are only special if castling
PieceKind::King if victim.is_some_and(|victim| victim.color() == piece.color()) => {
PieceKind::King
if victim
.is_some_and(|victim| victim.color() == piece.color() && victim.is_rook()) =>
{
if to.file() > from.file() {
kind = Self::ShortCastle;
} else {
Expand Down Expand Up @@ -456,18 +459,23 @@ impl Move {
is_ok
}
}

/// Creates a [`Move`] from a string, according to the [Universal Chess Interface](https://en.wikipedia.org//wiki/Universal_Chess_Interface) notation, extracting extra info from the provided [`Position`]
///
/// Will return a [`anyhow::Error`] if the string is invalid in any way.
///
/// # Example
/// ```
/// # use chessie::{Move, Square, MoveKind, PieceKind, Position};
/// // A sample test position for discovering promotion bugs.
/// # use chessie::*;
/// let position = Position::from_fen("n1n5/PPPk4/8/8/8/8/4Kppp/5N1N b - - 0 1 ").unwrap();
/// let b7c8b = Move::from_uci(&position, "b7c8b");
/// assert!(b7c8b.is_ok());
/// assert_eq!(b7c8b.unwrap(), Move::new(Square::B7, Square::C8, MoveKind::promotion_capture(PieceKind::Bishop)));
///
/// // Automatically parses castling moves in standard notation to use the KxR format
/// let position = Position::from_fen("r3k2r/p1ppqpb1/bn2pnp1/3PN3/1p2P3/2N2Q1p/PPPBBPPP/R3K2R w KQkq - 0 1").unwrap();
/// let e1c1 = Move::from_uci(&position, "e1c1");
/// // Rook is on A1
/// assert_eq!(e1c1.unwrap(), Move::new(Square::E1, Square::A1, MoveKind::LongCastle));
/// ```
pub fn from_uci(position: &Position, uci: &str) -> Result<Self> {
// Extract the to/from squares
Expand Down Expand Up @@ -550,10 +558,10 @@ impl Move {
pub fn into_standard_castle(self) -> Self {
if self.is_short_castle() {
let new_to = Square::new(File::G, self.from().rank());
Self::new(self.from(), new_to, self.kind())
Self::new(self.from(), new_to, MoveKind::ShortCastle)
} else if self.is_long_castle() {
let new_to = Square::new(File::C, self.from().rank());
Self::new(self.from(), new_to, self.kind())
Self::new(self.from(), new_to, MoveKind::LongCastle)
} else {
// If this move isn't a castle, no modification needs to be done
self
Expand Down
15 changes: 9 additions & 6 deletions chessie/src/position.rs
Original file line number Diff line number Diff line change
Expand Up @@ -583,25 +583,26 @@ impl Position {
if mv.is_capture() {
// If this move was en passant, the piece we captured isn't at `to`, it's one square behind
let victim_square = if mv.is_en_passant() {
// Safety: En passant cannot occur on the first or eighth, so this is guaranteed to have a square behind it.
// Safety: En passant cannot occur on the first or eighth rank, so this is guaranteed to have a square behind it.
unsafe { to.backward_by(color, 1).unwrap_unchecked() }
} else {
to
};

// Safety: This is a capture; there *must* be a piece at the destination square.
let victim = unsafe { self.take(victim_square).unwrap_unchecked() };
let victim = self.take(victim_square).unwrap();
// let victim = unsafe { self.take(victim_square).unwrap_unchecked() };
let victim_color = victim.color();

// If the capture was on a rook's starting square, disable that side's castling.
if self.castling_rights[victim_color]
.long
.is_some_and(|sq| to == sq)
.is_some_and(|sq| victim_square == sq)
{
self.clear_long_castling_rights(victim_color);
} else if self.castling_rights[victim_color]
.short
.is_some_and(|sq| to == sq)
.is_some_and(|sq| victim_square == sq)
{
self.clear_short_castling_rights(victim_color);
}
Expand All @@ -614,7 +615,8 @@ impl Position {
self.key.hash_optional_ep_square(self.ep_square());
} else if mv.is_short_castle() {
// Safety; This is a castle. There *must* be a Rook at `to`.
let rook = unsafe { self.take(to).unwrap_unchecked() };
// let rook = unsafe { self.take(to).unwrap_unchecked() };
let rook = self.take(to).unwrap();
self.place(rook, Square::rook_short_castle(color));

// The King doesn't actually move to the Rook, so update the destination square
Expand All @@ -624,7 +626,8 @@ impl Position {
self.clear_castling_rights(color);
} else if mv.is_long_castle() {
// Safety; This is a castle. There *must* be a Rook at `to`.
let rook = unsafe { self.take(to).unwrap_unchecked() };
// let rook = unsafe { self.take(to).unwrap_unchecked() };
let rook = self.take(to).unwrap();
self.place(rook, Square::rook_long_castle(color));

// The King doesn't actually move to the Rook, so update the destination square
Expand Down

0 comments on commit 6842b34

Please sign in to comment.