// zobrist.rs use crate::types::Color; use crate::position::Position; pub struct Zobrist { pub pieces: [[u64; 64]; 7], pub colors: [[u64; 64]; 2], pub side: u64, pub castling: [u64; 16], pub ep: [u64; 65], } impl Zobrist { pub fn new() -> Self { let mut state: u64 = 1070372; let mut next = || -> u64 { let mut res = 0; for _ in 0..64 { let bit = ((state >> 0) ^ (state >> 2) ^ (state >> 3) ^ (state >> 5)) & 1; state = (state >> 1) | (bit << 15); res = (res << 1) | (state & 1); } res }; let mut z = Self { pieces: [[0; 64]; 7], colors: [[0; 64]; 2], side: next(), castling: [0; 16], ep: [0; 65], }; for p in 1..=6 { for s in 0..64 { z.pieces[p][s] = next(); } } for c in 0..2 { for s in 0..64 { z.colors[c][s] = next(); } } for c in 0..16 { z.castling[c] = next(); } for e in 0..65 { z.ep[e] = next(); } z } pub fn hash(&self, pos: &Position) -> u64 { let mut h = 0; for p in 1..=6 { let mut bb = pos.pieces[p]; while bb != 0 { let sq = bb.trailing_zeros() as usize; h ^= self.pieces[p][sq]; bb &= bb - 1; } } for c in 0..2 { let mut bb = pos.colors[c]; while bb != 0 { let sq = bb.trailing_zeros() as usize; h ^= self.colors[c][sq]; bb &= bb - 1; } } if pos.side_to_move == Color::Black { h ^= self.side; } h ^= self.castling[pos.castling_rights as usize]; h ^= self.ep[pos.ep_square as usize]; h } }