aboutsummaryrefslogtreecommitdiff
path: root/src/board/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/board/mod.rs')
-rw-r--r--src/board/mod.rs49
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};