Add perft function and fix move generator bugs using perftree

This commit is contained in:
2024-07-01 23:29:56 +03:00
parent 941c14c199
commit 2a1a3224cb
7 changed files with 348 additions and 40 deletions

View File

@@ -115,7 +115,6 @@ impl Board {
moves.extend(self.pseudo_moves(color, Kind::King));
moves
}
pub fn pseudo_moves(&self, color: Color, kind: Kind) -> Vec<Move> {
let all_occupancies = self.get_all_occupancies();
let (pieces, enemy_occupancies, own_occupancies) = match color {
@@ -147,20 +146,18 @@ impl Board {
}
}
pub fn make_move_and_reset(&mut self, mv: Move, color: Color) -> Vec<Board> {
let mut board_variants = vec![];
pub fn make_move_and_reset(&mut self, mv: Move, color: Color) -> bool {
let original_board = self.clone();
if self.make_move(mv, color) {
board_variants.push(self.clone());
}
let result = self.make_move(mv, color);
*self = original_board;
board_variants
result
}
pub fn make_move(&mut self, mv: Move, color: Color) -> bool {
self.update_board_state(&mv, color);
self.state.update_castling_state(mv.source as u8, color);
self.state.next_turn();
self.state.change_side();
let pieces = match color {
Color::White => &self.white_pieces,
@@ -180,10 +177,12 @@ impl Board {
match &mv.move_type {
MoveType::Quiet => {
Board::move_piece(mv.source as u8, mv.target as u8, own_pieces);
self.state.set_en_passant_target_square(None);
}
MoveType::Capture => {
Board::move_piece(mv.source as u8, mv.target as u8, own_pieces);
Board::remove_piece(mv.target as u8, opponent_pieces);
self.state.set_en_passant_target_square(None);
}
MoveType::EnPassant => {
Board::move_piece(mv.source as u8, mv.target as u8, own_pieces);
@@ -198,15 +197,18 @@ impl Board {
MoveType::Promotion(promote) => {
Board::remove_piece(mv.source as u8, own_pieces);
Board::promote_piece(mv.target as u8, own_pieces, *promote);
self.state.set_en_passant_target_square(None);
}
MoveType::PromotionCapture(promote) => {
Board::remove_piece(mv.source as u8, own_pieces);
Board::remove_piece(mv.target as u8, opponent_pieces);
Board::promote_piece(mv.target as u8, own_pieces, *promote);
self.state.set_en_passant_target_square(None);
}
MoveType::Castle => {
Board::move_piece(mv.source as u8, mv.target as u8, own_pieces);
Board::move_rook_castle(mv.target as u8, own_pieces);
self.state.set_en_passant_target_square(None);
}
}
}
@@ -465,4 +467,25 @@ mod tests {
Ok(())
}
#[test]
fn test_perftree_snapshots() -> Result<(), String> {
init_attacks();
let mut game = from_fen("rnbqkbnr/ppppp1pp/5p2/7Q/8/4P3/PPPP1PPP/RNB1KBNR w KQkq - 0 1")?;
for mv in game.board.pseudo_moves_all(Color::Black) {
if game.board.make_move_and_reset(mv, Color::Black) {
println!("{:?}", mv)
}
}
let mut game = from_fen("rnbqkbnr/1ppppppp/p7/8/Q7/2P5/PP1PPPPP/RNB1KBNR w KQkq - 0 1")?;
for mv in game.board.pseudo_moves_all(Color::Black) {
if game.board.make_move_and_reset(mv, Color::Black) {
println!("{:?}", mv)
}
}
Ok(())
}
}