diff options
author | eug-vs <eugene@eug-vs.xyz> | 2023-01-25 02:10:40 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2023-01-25 02:10:40 +0300 |
commit | 05e6d002225f561c9725b25ef7960bc10421f723 (patch) | |
tree | ab0c3b0fa867a647fbb7471e99931bac9cc09f26 | |
parent | a56193bab4739b74cb7786351659b2c597940685 (diff) | |
download | chessnost-05e6d002225f561c9725b25ef7960bc10421f723.tar.gz |
feat: compute zobrist hash of the position
-rw-r--r-- | src/board/mod.rs | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/src/board/mod.rs b/src/board/mod.rs index 2085894..18e5e7f 100644 --- a/src/board/mod.rs +++ b/src/board/mod.rs @@ -1,3 +1,4 @@ +use rand::Rng; use crate::{bitboard::{Bitboard, serialize_bitboard, bitscan, pop_count}, moves::{Move, MoveKind}, attacks::Attacks, square::Square}; mod engine; @@ -22,6 +23,10 @@ pub struct Board { /// ``` pub castling_rights: [[bool; 2]; 2], + /// Zobrist hash of the current position + pub hash: u64, + + zobrist_seed: [u64; 781], attacks: Attacks, } @@ -105,15 +110,21 @@ impl Board { } } + let mut rng = rand::thread_rng(); + let zobrist_seed = [(); 781].map(|_| rng.gen()); + let mut board = Self { pieces, occupancy: 0, ply: 0, attacks: Attacks::new(), castling_rights: [[true; 2]; 2], // TODO: actualy parse from FEN - ep_target: None, + ep_target: None, // TODO: parse from FEN + hash: 0, + zobrist_seed, }; board.update_occupancy(); + board.update_zobrist_hash(); board } @@ -154,6 +165,40 @@ impl Board { occupancy } + /// Compute and store zobrist hash of the current position + /// https://www.chessprogramming.org/Zobrist_Hashing + fn update_zobrist_hash(&mut self) { + self.hash = 0; + + if self.color() == Color::Black { + self.hash ^= match self.zobrist_seed.last() { + Some(x) => x, + None => panic!("Something is wrong with zobrist seed list"), + }; + } + + for (piece_id, bitboard) in self.pieces.iter().enumerate() { + for square in serialize_bitboard(*bitboard) { + self.hash ^= self.zobrist_seed[piece_id * 64 + square as usize]; + } + } + + for color in 0..2 { + for castle_side in 0..2 { + if self.castling_rights[color][castle_side] { + self.hash ^= self.zobrist_seed[(12 * 64) + color * 2 + castle_side]; + } + } + } + + match self.ep_target { + Some(square) => { + self.hash ^= self.zobrist_seed[(12 * 64 + 4) + square.file() as usize]; + }, + None => {}, + } + } + pub fn print(&self) { println!(); for rank in (0..8).rev() { @@ -678,8 +723,6 @@ impl Color { #[cfg(test)] mod tests { - use std::f32::INFINITY; - use super::*; use crate::{bitboard::{pop_count, bitscan, print}, square::Square}; |