#include "engine/ttable.h" void ttable_init() { tbucket_t *table = calloc(TABLE_SIZE * sizeof(*table)); for (int i = 0; i < PIECE_TYPE_COUNT; i++) { for (int j = 0; j < 64; j++) { zobrist_keys.piece[i][j] = random_u64(); } } for (int i = 0; i < CASTLE_COUNT; i++) { zobrist_keys.castle[i] = random_u64(); } for (int i = 0; i < TURN_COUNT; i++) { zobrist_keys.turn[i] = random_u64(); } for (int i = 0; i < 64; i++) { zobrist_keys.en_passant[i] = random_u64(); } } u64 zobrist_hash(position_t position) { u64 output = 0; for (int i = 0; i < 64; i++) { int piece_type = find_piece_on_square(&position, i); output ^= zobrist_keys.piece[piece_type][i]; } if (position.castling & WHITE_SHORT_CASTLE) { output ^= zobrist_keys.castle[0]; } if (position.castling & WHITE_LONG_CASTLE) { output ^= zobrist_keys.castle[1]; } if (position.castling & BLACK_SHORT_CASTLE) { output ^= zobrist_keys.castle[2]; } if (position.castling & BLACK_LONG_CASTLE) { output ^= zobrist_keys.castle[3]; } output ^= zobrist_keys.turn[position.turn]; output ^= zobrist_keys.en_passant[position.passantable_file]; return output; } void ttable_store( ttable_t *ttable, u64 key, move_t move, i16 score, i16 eval, u16 depth, u16 generation, u8 flag ) { tbucket_t *bucket = ttable + (key & MASK); tentry_t *best = bucket.entries; for (int i = 1; i < TT_BUCKET_SIZE; i++) { if (bucket.entries[i].depth >= best->depth) continue; best = bucket.entries + i; } tentry_t object; object.move = move; object.score = score; object.eval = eval; object.depth = depth; object.flag = flag; object.generation = generation; memcpy(best, &object, sizeof(object)); atomic_store_explicit(&best->key, key, memory_order_release); } tentry_t *ttable_probe(ttable_t *table, u64 key) { tbucket_t *bucket = ttable + key & MASK; for (int i = 0; i < TT_BUCKET_SIZE; i++) { if (atomic_load_explicit( &(bucket.entries + i)->key, memory_order_acquire ) != key) continue; return bucket.entries + i; } return NULL; }