Skip to content

Commit 19a10cf

Browse files
authored
fix: castling bug with taken pieces (#196)
* fixed bug that caused castling to add taken pieces * bring back panic comments and logic * fix formatting * fix expects in chess_move.from() * fix formatting again
1 parent e6a0e2a commit 19a10cf

File tree

1 file changed

+55
-9
lines changed

1 file changed

+55
-9
lines changed

src/game_logic/game_board.rs

Lines changed: 55 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,7 @@ impl GameBoard {
263263

264264
/// Reconstruct game history from a string of space-separated UCI moves
265265
/// Optionally verifies against an expected final FEN
266+
#[allow(clippy::expect_used)]
266267
pub fn reconstruct_history(&mut self, moves_str: &str, expected_fen: Option<&str>) {
267268
if moves_str.trim().is_empty() {
268269
return;
@@ -291,10 +292,33 @@ impl GameBoard {
291292
match uci.to_move(&current_position) {
292293
Ok(chess_move) => {
293294
// Track captures
294-
if let Some(captured_piece) =
295-
current_position.board().piece_at(chess_move.to())
296-
{
297-
self.taken_pieces.push(captured_piece);
295+
match chess_move {
296+
Move::Normal { .. } => {
297+
if let Some(captured_piece) =
298+
current_position.board().piece_at(chess_move.to())
299+
{
300+
self.taken_pieces.push(captured_piece);
301+
}
302+
}
303+
Move::EnPassant { .. } => {
304+
let from_square = chess_move
305+
.from()
306+
.expect("En passant move must have a 'from' square");
307+
let to_square = chess_move.to();
308+
let captured_pawn_square =
309+
Square::from_coords(to_square.file(), from_square.rank());
310+
if let Some(captured_piece) =
311+
current_position.board().piece_at(captured_pawn_square)
312+
{
313+
self.taken_pieces.push(captured_piece);
314+
}
315+
}
316+
Move::Castle { .. } => {
317+
// No piece is taken when castling.
318+
}
319+
Move::Put { .. } => {
320+
// Putting a piece on board, not a capture
321+
}
298322
}
299323

300324
// Apply the move
@@ -399,6 +423,7 @@ impl GameBoard {
399423

400424
/// Execute a move on the board
401425
/// Returns the executed Move if successful, None if illegal
426+
#[allow(clippy::expect_used)]
402427
pub fn execute_move(
403428
&mut self,
404429
from: Square,
@@ -407,11 +432,6 @@ impl GameBoard {
407432
) -> Option<Move> {
408433
let chess = self.position_ref().clone();
409434

410-
// Track captures before executing move
411-
if let Some(captured_piece) = chess.board().piece_at(to) {
412-
self.taken_pieces.push(captured_piece);
413-
}
414-
415435
// Find matching legal move
416436
let legal_moves = chess.legal_moves();
417437

@@ -472,6 +492,32 @@ impl GameBoard {
472492
});
473493

474494
if let Some(shakmaty_move) = matching_move {
495+
// It's a legal move. Check for capture.
496+
match *shakmaty_move {
497+
Move::Normal { .. } => {
498+
if let Some(captured_piece) = chess.board().piece_at(shakmaty_move.to()) {
499+
self.taken_pieces.push(captured_piece);
500+
}
501+
}
502+
Move::EnPassant { .. } => {
503+
let from_square = shakmaty_move
504+
.from()
505+
.expect("En passant move must have a 'from' square");
506+
let to_square = shakmaty_move.to();
507+
let captured_pawn_square =
508+
Square::from_coords(to_square.file(), from_square.rank());
509+
if let Some(captured_piece) = chess.board().piece_at(captured_pawn_square) {
510+
self.taken_pieces.push(captured_piece);
511+
}
512+
}
513+
Move::Castle { .. } => {
514+
// No piece is taken when castling.
515+
}
516+
Move::Put { .. } => {
517+
// Putting a piece on board, not a capture
518+
}
519+
}
520+
475521
// Execute move
476522
match chess.play(shakmaty_move) {
477523
Ok(new_chess) => {

0 commit comments

Comments
 (0)