const SEED: u128 = 0x8F2D7BAC4E1F9089327465A0FEBD13D6;
pub struct XorShiftState {
pub state: u128,
}
impl XorShiftState {
pub const fn new() -> Self {
Self { state: SEED }
}
pub const fn next_self(mut self) -> (u64, Self) {
let mut x = self.state;
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
self.state = x;
#[allow(clippy::cast_possible_truncation)]
let r = x as u64;
let r = r ^ (x >> 64) as u64;
(r, self)
}
pub fn gen_next(&mut self) -> u64 {
let mut x = self.state;
x ^= x >> 12;
x ^= x << 25;
x ^= x >> 27;
self.state = x;
#[allow(clippy::cast_possible_truncation)]
let r = x as u64;
r ^ (x >> 64) as u64
}
pub fn random_few_bits(&mut self) -> u64 {
let first = self.gen_next();
let second = self.gen_next();
let third = self.gen_next();
first & second & third
}
}
type ZobristHashes = ([[u64; 64]; 12], [u64; 8], [[u64; 4]; 2], u64);
const fn generate_zobrist_hash() -> ZobristHashes {
let mut state = XorShiftState::new();
let mut piece_keys = [[0; 64]; 12];
let mut i = 0;
while i < 12 {
let mut square = 0;
while square < 64 {
let key;
(key, state) = state.next_self();
piece_keys[i][square] = key;
square += 1;
}
i += 1;
}
let mut castle_keys = [[0; 4]; 2];
let mut i = 0;
while i < 2 {
let mut rule = 0;
while rule < 4 {
let key;
(key, state) = state.next_self();
castle_keys[i][rule] = key;
rule += 1;
}
i += 1;
}
let mut ep_keys = [0; 8];
let mut i = 0;
while i < 8 {
let key;
(key, state) = state.next_self();
ep_keys[i] = key;
i += 1;
}
let key;
(key, _) = state.next_self();
let side_key = key;
(piece_keys, ep_keys, castle_keys, side_key)
}
pub const PIECE_KEYS: [[u64; 64]; 12] = generate_zobrist_hash().0;
pub const EP_KEYS: [u64; 8] = generate_zobrist_hash().1;
pub const CASTLE_KEYS: [[u64; 4]; 2] = generate_zobrist_hash().2;
pub const SIDE_KEY: u64 = generate_zobrist_hash().3;