Minimax Algorithm in Game Theory | Set 5 (Zobrist Hashing)

18 Apr, 2022
Previous posts on this topic : Minimax Algorithm in Game Theory, Evaluation Function in Game Theory, Tic-Tac-Toe AI – Finding optimal move, Alpha-Beta Pruning.Zobrist Hashing is a hashing function that is widely used in 2 player board games. It is the most common hashing function used in transposition table. Transposition tables basically store the evaluated values of previous board states, so that if they are encountered again we simply retrieve the stored value from the transposition table. We will be covering transposition tables in a later article. In this article we shall take the example of chess board and implement a hashing function for that. 
 
// A matrix with random numbers initialized once
Table[#ofBoardCells][#ofPieces] 

// Returns Zobrist hash function for current conf-
// iguration of board.
function findhash(board):
    hash = 0
    for each cell on the board :
        if cell is not empty :
            piece = board[cell]
            hash ^= table[cell][piece]
    return hash
 
The idea behind Zobrist Hashing is that for a given board state, if there is a piece on a given cell, we use the random number of that piece from the corresponding cell in the table. If more bits are there in the random number the lesser chance of a hash collision. Therefore 64 bit numbers are commonly used as the standard and it is highly unlikely for a hash collision to occur with such large numbers. The table has to be initialized only once during the programs execution. Also the reason why Zobrist Hashing is widely used in board games is because when a player makes a move, it is not necessary to recalculate the hash value from scratch. Due to the nature of XOR operation we can simply use few XOR operations to recalculate the hash value. 
We shall try to find a hash value for the given board configuration. 
CPP
// A program to illustrate Zobrist Hashing Algorithm#include <bits/stdc++.h>using namespace std; unsigned long long int ZobristTable[8][8][12];mt19937 mt(01234567); // Generates a Random number from 0 to 2^64-1unsigned long long int randomInt(){    uniform_int_distribution<unsigned long long int>                                 dist(0, UINT64_MAX);    return dist(mt);} // This function associates each piece with// a numberint indexOf(char piece){    if (piece=='P')        return 0;    if (piece=='N')        return 1;    if (piece=='B')        return 2;    if (piece=='R')        return 3;    if (piece=='Q')        return 4;    if (piece=='K')        return 5;    if (piece=='p')        return 6;    if (piece=='n')        return 7;    if (piece=='b')        return 8;    if (piece=='r')        return 9;    if (piece=='q')        return 10;    if (piece=='k')        return 11;    else        return -1;} // Initializes the tablevoid initTable(){    for (int i = 0; i<8; i++)      for (int j = 0; j<8; j++)        for (int k = 0; k<12; k++)          ZobristTable[i][j][k] = randomInt();} // Computes the hash value of a given boardunsigned long long int computeHash(char board[8][9]){    unsigned long long int h = 0;    for (int i = 0; i<8; i++)    {        for (int j = 0; j<8; j++)        {            if (board[i][j]!='-')            {                int piece = indexOf(board[i][j]);                h ^= ZobristTable[i][j][piece];            }        }    }    return h;} // Main Functionint main(){    // Uppercase letters are white pieces    // Lowercase letters are black pieces    char board[8][9] =    {        "---K----",        "-R----Q-",        "--------",        "-P----p-",        "-----p--",        "--------",        "p---b--q",        "----n--k"    };     initTable();     unsigned long long int hashValue = computeHash(board);    printf("The hash value is     : %llu\n", hashValue);     //Move the white king to the left    char piece = board[0][3];     board[0][3] = '-';    hashValue ^= ZobristTable[0][3][indexOf(piece)];     board[0][2] = piece;    hashValue ^= ZobristTable[0][2][indexOf(piece)];      printf("The new hash value is : %llu\n", hashValue);     // Undo the white king move    piece = board[0][2];     board[0][2] = '-';    hashValue ^= ZobristTable[0][2][indexOf(piece)];     board[0][3] = piece;    hashValue ^= ZobristTable[0][3][indexOf(piece)];     printf("The old hash value is : %llu\n", hashValue);     return 0;}
The hash value is     : 14226429382419125366
The new hash value is : 15124945578233295113
The old hash value is : 14226429382419125366
This article is contributed by Akshay L Aradhya. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above. 
nidhi_biet
surinderdawra388
simmytarika5
Bitwise-XOR
Game Theory
Game Theory
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Chessboard Pawn-Pawn game
Find the winner of a game of removing any number of stones from the least indexed non-empty pile from given N piles
Josephus Problem | (Iterative Solution)
Find the player who will win by choosing a number in range [1, K] with sum total N
Game Theory (Normal-form Game) | Set 4 (Dominance Property-Pure Strategy)
Minesweeper Solver
Two player game in which a player can remove all occurrences of a number
Game of Nim with removal of one stone allowed
Maximum cells attacked by Rook or Bishop in given Chessboard
Classification of Algorithms with Examples