Add Zobrist hashing

This commit is contained in:
stefiosif
2024-10-06 03:31:33 +03:00
parent 70ba30ba1a
commit 28409d203a
8 changed files with 340 additions and 20 deletions

View File

@@ -10,6 +10,7 @@ use super::{
mailbox::Mailbox,
square::Square,
state::Castle,
zobrist::{zobrist_keys, ZobristHash},
};
impl PartialEq for Game {
@@ -25,6 +26,7 @@ pub struct Game {
pub board: Board,
pub history: History,
pub mailbox: Mailbox,
pub hash: ZobristHash,
}
impl Game {
@@ -33,6 +35,7 @@ impl Game {
board: Board::new(),
history: History::new(),
mailbox: Mailbox::new_from_board(&Board::new()),
hash: zobrist_keys().calculate_hash(&Board::new()),
}
}
@@ -49,32 +52,43 @@ impl Game {
.push_move_parameters(MoveParameters::build(self, mv));
let board = &mut self.board;
let hash = &mut self.hash;
let mailbox = &mut self.mailbox;
let color = board.state.current_player();
let pawn_move = board.is_pawn_move(mv.src);
let mut en_passant_square = None;
let capture_square = match color {
Color::White => mv.dst - 8,
Color::Black => mv.dst + 8,
};
let old_castling_ability = board.state.castling_ability;
let piece_at_src = mailbox.find_piece_at(mv.src).expect("Expected set piece");
let piece_at_src = mailbox
.find_piece_at(mv.src)
.expect("Expected piece at: {mv.src}");
let piece_at_dst = mailbox.find_piece_at(mv.dst);
match &mv.move_type {
MoveType::Quiet => {
board.move_piece(mv.src, mv.dst, piece_at_src);
mailbox.set_piece_at(mv.dst, mailbox.find_piece_at(mv.src));
hash.update_quiet(mv.src, mv.dst, piece_at_src, color);
mailbox.set_piece_at(mv.dst, Some(piece_at_src));
}
MoveType::Capture => {
let piece_at_dst = piece_at_dst.expect("Expected piece at: {mv.dst}");
board.move_piece(mv.src, mv.dst, piece_at_src);
board.remove_opponent_piece(mv.dst, piece_at_dst.expect("Expected set piece"));
mailbox.set_piece_at(mv.dst, mailbox.find_piece_at(mv.src));
board.remove_opponent_piece(mv.dst, piece_at_dst);
hash.update_capture(mv.src, mv.dst, piece_at_src, piece_at_dst, color);
mailbox.set_piece_at(mv.dst, Some(piece_at_src));
}
MoveType::EnPassant => {
board.move_piece(mv.src, mv.dst, piece_at_src);
let piece_to_remove_sq = match color {
Color::White => mv.dst - 8,
Color::Black => mv.dst + 8,
};
board.remove_opponent_piece(piece_to_remove_sq, PieceType::Pawn);
mailbox.set_piece_at(mv.dst, mailbox.find_piece_at(mv.src));
mailbox.set_piece_at(piece_to_remove_sq, None);
let piece_at_capture = mailbox
.find_piece_at(capture_square)
.expect("Expected piece at: {capture_square}");
board.remove_opponent_piece(capture_square, PieceType::Pawn);
hash.update_en_passant(mv.src, mv.dst, piece_at_src, piece_at_capture, color);
mailbox.set_piece_at(mv.dst, Some(piece_at_src));
mailbox.set_piece_at(capture_square, None);
}
MoveType::DoublePush => {
board.move_piece(mv.src, mv.dst, piece_at_src);
@@ -82,17 +96,36 @@ impl Game {
Color::White => Some(mv.src + 8),
Color::Black => Some(mv.src.saturating_sub(8)),
};
mailbox.set_piece_at(mv.dst, mailbox.find_piece_at(mv.src));
hash.update_double_push(
mv.src,
mv.dst,
piece_at_src,
color,
board.state.en_passant_square,
);
mailbox.set_piece_at(mv.dst, Some(piece_at_src));
}
MoveType::Promotion(promote) => {
board.remove_own_piece(mv.src, piece_at_src);
board.promote_piece(mv.dst, promote);
hash.update_promotion(mv.src, mv.dst, piece_at_src, promote, color);
mailbox.set_piece_at(mv.dst, Some(promote.into_piece_type()));
}
MoveType::PromotionCapture(promote) => {
board.remove_own_piece(mv.src, piece_at_src);
board.remove_opponent_piece(mv.dst, piece_at_dst.expect("Expected set piece"));
board.remove_opponent_piece(
mv.dst,
piece_at_dst.expect("Expected piece at dst: {mv.dst}"),
);
board.promote_piece(mv.dst, promote);
hash.update_promotion_capture(
mv.src,
mv.dst,
piece_at_src,
piece_at_dst.unwrap(),
promote,
color,
);
mailbox.set_piece_at(mv.dst, Some(promote.into_piece_type()));
}
MoveType::Castle => {
@@ -104,7 +137,8 @@ impl Game {
};
board.move_piece(rook_src, rook_dst, PieceType::Rook);
board.state.set_castling_ability(color, Castle::None);
mailbox.set_piece_at(mv.dst, mailbox.find_piece_at(mv.src));
hash.update_castle(mv.src, mv.dst, piece_at_src, rook_src, rook_dst, color);
mailbox.set_piece_at(mv.dst, Some(piece_at_src));
mailbox.set_piece_at(rook_src, None);
mailbox.set_piece_at(rook_dst, Some(PieceType::Rook));
}
@@ -114,6 +148,14 @@ impl Game {
board
.state
.update_game_state(mv, color, pawn_move, en_passant_square);
hash.update_side_to_move_key();
if let Some(old_en_passant) = board.state.en_passant_square {
hash.update_en_passant_keys(old_en_passant);
}
hash.update_castling_ability_keys(old_castling_ability, board.state.castling_ability);
}
pub fn unmake_move(&mut self) {
@@ -127,6 +169,10 @@ impl Game {
board.state.revert_full_move(color_before_move);
board.state.en_passant_square = move_parameters.en_passant_square;
if let Some(hash) = move_parameters.zobrist_hash {
self.hash = hash;
}
if let Some(new_castling_ability) = move_parameters.castling_ability {
board.state.castling_ability = new_castling_ability;
}