Add perft function and fix move generator bugs using perftree
This commit is contained in:
39
src/board.rs
39
src/board.rs
@@ -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(())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user