From 5db45a760a8eebf5de2efd5d784c75ddf93f0640 Mon Sep 17 00:00:00 2001 From: Bruno Raoult Date: Wed, 15 May 2024 18:36:30 +0200 Subject: [PATCH] fen: calc pos hash, hash: fix zobrist_init, add zobrist_verify --- src/fen.c | 4 +++- src/hash.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/hash.h | 1 + 3 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/fen.c b/src/fen.c index 2818000..6f8d2c1 100644 --- a/src/fen.c +++ b/src/fen.c @@ -250,8 +250,10 @@ end: } if (fen_check(&tmppos) < 0) return NULL; + tmppos.key = zobrist_calc(&tmppos); if (!pos) - pos = pos_dup(&tmppos); + pos = pos_new(); + pos_copy(&tmppos, pos); //puts("prout 1"); //pos_print_raw(&tmppos, 1); //puts("prout 2"); diff --git a/src/hash.c b/src/hash.c index befa61c..b8eb00d 100644 --- a/src/hash.c +++ b/src/hash.c @@ -51,6 +51,7 @@ void zobrist_init(void) /** * zobrist_calc() - calculate a position zobrist hash. + * @pos: &position * * Normally, Zobrist keys are incrementally calculated when doing or * undoing a move. @@ -58,6 +59,7 @@ void zobrist_init(void) * - When starting a new position * - To verify incremental Zobrist calculation is correct * + * @return: @pos Zobrist key */ key_t zobrist_calc(pos_t *pos) { @@ -76,12 +78,64 @@ key_t zobrist_calc(pos_t *pos) } } } - key ^= pos->castle; - key ^= EP_ZOBRIST_IDX(pos->en_passant); + key ^= zobrist_castling[pos->castle]; + key ^= zobrist_ep[EP_ZOBRIST_IDX(pos->en_passant)]; return key; } +/** + * zobrist_verify() - verify current position Zobrist key. + * @pos: &position + * + * Verify that position Zobrist key matches a full Zobrist calculation. + * This function cannot be called if DEBUG_HASH is not set. + * + * @return: True if Zobrist key is OK. + */ +#ifdef DEBUG_HASH +bool zobrist_verify(pos_t *pos) +{ + key_t diff, key = zobrist_calc(pos); + + if (pos->key == key) + return true; + + printf("key verify: cur=%#lx != %#lx\n", pos->key, key); + + /* try to find-out the key in different zobrist tables */ + diff = pos->key ^ key; + + for (color_t c = WHITE; c <= BLACK; ++c) { + for (piece_type_t p = PAWN; p <= KING; ++p) + for (square_t sq = A1; sq <= H8; ++sq) + if (diff == zobrist_pieces[MAKE_PIECE(p, c)][sq]) { + warn(true, "zobrist difference is piece:[%s][%s]\n", + piece_to_fen(MAKE_PIECE(p, c)), sq_to_string(sq)); + goto end; + } + } + for (castle_rights_t c = CASTLE_NONE; c <= CASTLE_ALL; ++c) + if (diff == zobrist_castling[c]) { + warn(true, "zobrist difference is castling:[%d]\n", c); + goto end; + } + + for (file_t f = FILE_A; f <= FILE_H; ++f) + if (diff == zobrist_ep[f]) { + warn(true, "zobrist difference is ep:[%d]\n", f); + goto end; + } + if (diff == zobrist_turn) { + warn(true, "zobrist difference is turn\n"); + goto end; + } + warn(true, "zobrist diff %lx is unknown\n", diff); +end: + return false; +} +#endif + /** * hash_create() - hashtable creation. * @sizemb: s32 size of hash table in Mb diff --git a/src/hash.h b/src/hash.h index 76cc880..e639250 100644 --- a/src/hash.h +++ b/src/hash.h @@ -90,6 +90,7 @@ extern hasht_t hash_tt; /* main transposition table */ void zobrist_init(void); key_t zobrist_calc(pos_t *pos); +bool zobrist_verify(pos_t *pos); int hash_create(int Mb); void hash_clear(void);