zobrist.c (2216B)
1 #include "zobrist.h" 2 #include "board.h" 3 #include "piece.h" 4 #include "random.h" 5 #include "utils.h" 6 7 U64 castle_keys[16]; 8 U64 enpassant_keys[64]; 9 U64 piece_keys[16][64]; 10 U64 side_key; 11 12 U64 zobrist_key_side(void) { return side_key; } 13 U64 zobrist_key_castle(int exp) { return castle_keys[exp]; } 14 U64 zobrist_key_enpassant(Square square) { return enpassant_keys[square]; } 15 U64 zobrist_key_piece(Piece piece, Square square) { 16 return piece_keys[piece_index(piece)][square]; 17 } 18 19 void init_hash_keys() { 20 random_state_reset(); 21 22 for (int piece = PAWN; piece <= KING; piece++) { 23 int piece_index_white = piece_index(piece_get(piece, WHITE)); 24 int piece_index_black = piece_index(piece_get(piece, BLACK)); 25 for (int square = 0; square < 64; square++) { 26 piece_keys[piece_index_white][square] = random_get_U64(); 27 piece_keys[piece_index_black][square] = random_get_U64(); 28 } 29 } 30 31 for (int square = 0; square < 64; square++) { 32 enpassant_keys[square] = random_get_U64(); 33 } 34 35 for (int castle = 0; castle < 16; castle++) { 36 castle_keys[castle] = random_get_U64(); 37 } 38 39 side_key = random_get_U64(); 40 } 41 42 void zobrist_init(void) { init_hash_keys(); } 43 44 U64 zobrist_hash(const Board *board) { 45 U64 key_final = C64(0); 46 Square square; 47 48 for (int piece = PAWN; piece <= KING; piece++) { 49 Piece piece_white = piece_get(piece, WHITE); 50 U64 bitboard_white = board_pieceSet(board, piece_white); 51 int piece_white_index = piece_index(piece_white); 52 53 bitboard_for_each_bit(square, bitboard_white) { 54 key_final ^= piece_keys[piece_white_index][square]; 55 } 56 57 Piece piece_black = piece_get(piece, BLACK); 58 U64 bitboard_black = board_pieceSet(board, piece_black); 59 int piece_black_index = piece_index(piece_black); 60 61 bitboard_for_each_bit(square, bitboard_black) { 62 key_final ^= piece_keys[piece_black_index][square]; 63 } 64 } 65 66 key_final ^= castle_keys[board_castle(board)]; 67 68 if (board_side(board)) key_final ^= side_key; 69 if (board_enpassant(board) != no_sq) 70 key_final ^= enpassant_keys[board_enpassant(board)]; 71 72 return key_final; 73 }