Please help with Zobrist key incremental updates
Posted: Wed Sep 16, 2020 9:32 pm
Hi guys
Currently I have this code to init hash keys and generate hash key for a position:
Now within my make_move function I'm trying to generate_position_key() at the end of the move to see how it SHOULD look like.
On the other hand I'm trying to incrementally update pieces/enpassant/side/castling rights.
It's too complicated and incrementally updated results do not match with the hash keys generated from scratch every time.
I'm trying to XOR pieces and all the stuff back in force but feel really confused.
Could you please give me a clue of how to divide and conquer this process?
Something line first learn to update key if piece is disappeared, then when it appears on new square and so on.
I don't want to clone how other engines doing it and want to implement it on my own.
Please show me the path.
Currently I have this code to init hash keys and generate hash key for a position:
Code: Select all
// random piece keys [piece][square]
U64 piece_keys[12][64];
// castling keys [bits]
U64 castle_keys[16];
// enpassant keys [square]
U64 enpassant_keys[64];
// side to move keys
U64 side_keys[2];
// init hash keys (with random U64 numbers)
void init_hash_keys()
{
// loop over piece codes
for (int piece = P; piece <= k; piece++)
{
// loop over squares
for (int square = 0; square < 64; square++)
{
// init piece keys
piece_keys[piece][square] = get_random_U64_number();
}
}
// init side to move keys
side_keys[white] = get_random_U64_number();
side_keys[black] = get_random_U64_number();
// loop over board squares
for (int square = 0; square < 64; square++)
// init enpassant keys
enpassant_keys[square] = get_random_U64_number();
// loop over castling keys
for (int index = 0; index < 16; index++)
// init castling keys
castle_keys[index] = get_random_U64_number();
}
// generate unique position key
U64 generate_hash_key()
{
// final key
U64 hash_key = 0ULL;
// piece bitboard copy
U64 bitboard;
// loop over piece bitboards
for (int piece = P; piece < k; piece++)
{
// init piece bitboard copy
bitboard = bitboards[piece];
// loop over bitboard pieces
while (bitboard)
{
// get piece square
int square = get_ls1b_index(bitboard);
// hash pieces
hash_key ^= piece_keys[piece][square];
// reset LS1B
pop_bit(bitboard, square);
}
}
// hash side to move
hash_key ^= side_keys[side];
// if enpassant square available
if (enpassant != no_sq)
// hash enpassant square
hash_key ^= enpassant_keys[enpassant];
// hash castling
hash_key ^= castle_keys[castle];
// return final key
return hash_key;
}
On the other hand I'm trying to incrementally update pieces/enpassant/side/castling rights.
It's too complicated and incrementally updated results do not match with the hash keys generated from scratch every time.
I'm trying to XOR pieces and all the stuff back in force but feel really confused.
Could you please give me a clue of how to divide and conquer this process?
Something line first learn to update key if piece is disappeared, then when it appears on new square and so on.
I don't want to clone how other engines doing it and want to implement it on my own.
Please show me the path.