Skip to content

Commit

Permalink
feat: undo move
Browse files Browse the repository at this point in the history
  • Loading branch information
Kacperacy committed Jan 19, 2025
1 parent d8f5a67 commit 2445ff7
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 2 deletions.
61 changes: 59 additions & 2 deletions src/board/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,13 @@ impl Board {
moves: Vec::new(),
zobrist_history: Vec::new(),
fen_history: Vec::new(),
game_state_history: Vec::new(),
game_state_history: vec![GameState {
captured_piece: None,
en_passant_square: None,
castling_rights: CASTLING_RIGHTS[0] | CASTLING_RIGHTS[1],
fifty_move_ply_count: 0,
current_zobrist: 0,
}],
}
}

Expand All @@ -136,7 +142,7 @@ impl Board {
self.moves = Vec::new();
self.zobrist_history = Vec::new();
self.fen_history = Vec::new();
self.game_state_history = Vec::new();
self.game_state_history = vec![self.game_state];
}

pub fn set_fen(&mut self, fen: &str) {
Expand Down Expand Up @@ -482,4 +488,55 @@ impl Board {
self.fen_history.push(self.to_fen());
self.moves.push(*mv);
}

pub fn undo_move(&mut self, mv: &Move) {
self.turn = self.turn.opposite();
let last_move = self.moves.pop().unwrap();

if last_move != *mv {
panic!("Invalid move");
}

if mv.promotion == Some(Piece::Pawn) {
self.remove_piece(mv.color, mv.promotion.unwrap(), mv.to);
self.add_piece(mv.color, Piece::Pawn, mv.to);
}

self.move_piece(mv.color, mv.piece, mv.to, mv.from);

if mv.capture.is_some() {
let mut capture_square = mv.to as i32;

if mv.en_passant {
capture_square -= match mv.color {
Color::White => MOVE_DOWN,
Color::Black => MOVE_UP,
};
}

self.add_piece(
mv.color.opposite(),
mv.capture.unwrap(),
capture_square as usize,
);
}

if mv.piece == Piece::King {
if mv.castling {
let (rook_from, rook_to) = match mv.to {
2 => (0, 3),
6 => (7, 5),
_ => panic!("Invalid castling move"),
};

self.move_piece(mv.color, Piece::Rook, rook_to, rook_from);
}
}

self.game_state_history.pop();
self.game_state = self.game_state_history.last().unwrap().clone();
self.zobrist_history.pop();
self.fen_history.pop();
self.ply -= 1;
}
}
43 changes: 43 additions & 0 deletions tests/board_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -755,4 +755,47 @@ mod tests {

assert_eq!(castling, castling_assert);
}

#[test]
fn test_make_move() {
let mut board = Board::init();
let mv = Move {
from: 12,
to: 28,
piece: Piece::Pawn,
color: Color::White,
en_passant: false,
castling: false,
promotion: None,
capture: None,
};

board.make_move(&mv);

assert!(board.pieces[Color::White as usize][Piece::Pawn as usize].is_set(28));
assert!(!board.pieces[Color::White as usize][Piece::Pawn as usize].is_set(12));
}

#[test]
fn test_undo_move() {
let mut board = Board::init();
let fen_before = board.to_fen();
let mv = Move {
from: 12,
to: 28,
piece: Piece::Pawn,
color: Color::White,
en_passant: false,
castling: false,
promotion: None,
capture: None,
};

board.make_move(&mv);
board.undo_move(&mv);

assert!(board.pieces[Color::White as usize][Piece::Pawn as usize].is_set(12));
assert!(!board.pieces[Color::White as usize][Piece::Pawn as usize].is_set(28));
assert_eq!(fen_before, board.to_fen());
}
}

0 comments on commit 2445ff7

Please sign in to comment.