Add Zobrist hashing
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user