aboutsummaryrefslogtreecommitdiff
path: root/src/board/zobrist.rs
diff options
context:
space:
mode:
authoreug-vs <eugene@eug-vs.xyz>2023-02-21 13:26:18 +0300
committereug-vs <eugene@eug-vs.xyz>2023-02-21 13:26:18 +0300
commit0d5c2eb1666d3038fa87895cc98eadc673c54a3a (patch)
treea8a3ae3d618bfb33c214b990b3206cb158b1c527 /src/board/zobrist.rs
parent08e27cdb8aa546833927b678d0a0d3ade1e91ef0 (diff)
downloadchessnost-0d5c2eb1666d3038fa87895cc98eadc673c54a3a.tar.gz
refactor: separate zobrist module
Diffstat (limited to 'src/board/zobrist.rs')
-rw-r--r--src/board/zobrist.rs79
1 files changed, 79 insertions, 0 deletions
diff --git a/src/board/zobrist.rs b/src/board/zobrist.rs
new file mode 100644
index 0000000..e282074
--- /dev/null
+++ b/src/board/zobrist.rs
@@ -0,0 +1,79 @@
+use rand::{rngs::StdRng,SeedableRng,Rng};
+
+use crate::{square::Square, bitboard::BitboardFns};
+
+use super::{Board, Color, PieceType, CastlingSide};
+
+
+const TOTAL_PIECES: usize = 12;
+const TOTAL_SQUARES: usize = 64;
+const TOTAL_FILES: usize = 8;
+const TOTAL_CASTLING_RIGHTS: usize = 4;
+const ZOBRIST_SEED_SIZE: usize = TOTAL_SQUARES * TOTAL_PIECES + TOTAL_CASTLING_RIGHTS + TOTAL_FILES + 1;
+
+pub type ZobristSeed = [u64; ZOBRIST_SEED_SIZE];
+
+pub trait Zobrist {
+ fn seed() -> ZobristSeed;
+
+ /// Compute store zobrist hash of the current position
+ /// https://www.chessprogramming.org/Zobrist_Hashing
+ fn compute_hash(&mut self) -> ();
+
+ fn zobrist_toggle_piece(&mut self, piece_type: PieceType, square: Square) -> ();
+ fn zobrist_toggle_castling_right(&mut self, color: Color, side: CastlingSide) -> ();
+ fn zobrist_toggle_ep_square(&mut self, ep_square: Square) -> ();
+ fn zobrist_toggle_color(&mut self) -> ();
+}
+
+impl Zobrist for Board {
+ fn seed() -> ZobristSeed {
+ let mut rng = StdRng::seed_from_u64(228);
+ [(); ZOBRIST_SEED_SIZE].map(|_| rng.gen())
+ }
+
+ fn compute_hash(&mut self) -> () {
+ self.hash = 0;
+
+ for piece_id in 0..self.piece_sets.len() {
+ for square in self.piece_sets[piece_id].serialize() {
+ self.zobrist_toggle_piece(PieceType::from(piece_id), square);
+ }
+ }
+ for color in [Color::White, Color::Black] {
+ for castle_side in [CastlingSide::King, CastlingSide::Queen] {
+ if self.castling_rights[color as usize][castle_side as usize] {
+ self.zobrist_toggle_castling_right(color, castle_side)
+ }
+ }
+ }
+
+ match self.ep_target {
+ Some(square) => self.zobrist_toggle_ep_square(square),
+ None => {},
+ }
+
+ if self.color() == Color::Black {
+ self.zobrist_toggle_color();
+ }
+ }
+
+ fn zobrist_toggle_piece(&mut self, piece_type: PieceType, square: Square) -> () {
+ self.hash ^= self.zobrist_seed[piece_type as usize * TOTAL_SQUARES + square as usize];
+ }
+
+ fn zobrist_toggle_castling_right(&mut self, color: Color, side: CastlingSide) -> () {
+ self.hash ^= self.zobrist_seed[(TOTAL_PIECES * TOTAL_SQUARES) + color as usize * 2 + side as usize];
+ }
+
+ fn zobrist_toggle_ep_square(&mut self, ep_square: Square) -> () {
+ self.hash ^= self.zobrist_seed[(TOTAL_PIECES * TOTAL_SQUARES + TOTAL_CASTLING_RIGHTS) + ep_square.file() as usize];
+ }
+
+ fn zobrist_toggle_color(&mut self) -> () {
+ self.hash ^= match self.zobrist_seed.last() {
+ Some(x) => x,
+ None => panic!("Something is wrong with zobrist seed list"),
+ };
+ }
+}