// A Java program to illustrate Zobrist Hashing Algorithm
import java.util.*;
public class GFG {
public static List<List<List<Integer>>> ZobristTable = new ArrayList<>();
// mt19937 mt(01234567);
public static void initialise() {
for (int i = 0; i < 8; i++) {
ZobristTable.add(new ArrayList<>());
for (int j = 0; j < 8; j++) {
ZobristTable.get(i).add(new ArrayList<>());
for (int k = 0; k < 12; k++) {
ZobristTable.get(i).get(j).add(0);
}
}
}
}
// Generates a Random number from 0 to 2^64-1
public static long randomLong() {
long min = 0L;
long max = (long) Math.pow(2, 64);
Random rnd = new Random();
return rnd.nextLong() * (max - min) + min;
}
// This function associates each piece with a number
public static int 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 table
public static void initTable() {
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
for (int k = 0; k < 12; k++) {
Random rnd = new Random();
ZobristTable.get(i).get(j).set(k, (int) randomLong());
}
}
}
}
// Computes the hash value of a given board
public static int computeHash(List<List<Character>> board) {
int h = 0;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (board.get(i).get(j) != '-') {
int piece = indexOf(board.get(i).get(j));
h ^= ZobristTable.get(i).get(j).get(piece);
}
}
}
return h;
}
public static void main(String[] args) {
// Main Function
// Uppercase letters are white pieces
// Lowercase letters are black pieces
List<List<Character>> board = new ArrayList<>();
board.add(new ArrayList<>(Arrays.asList('-', '-', '-', 'K', '-', '-', '-', '-')));
board.add(new ArrayList<>(Arrays.asList('-', 'R', '-', '-', '-', '-', 'Q', '-')));
board.add(new ArrayList<>(Arrays.asList('-', '-', '-', 'K', '-', '-', '-', '-')));
board.add(new ArrayList<>(Arrays.asList('-', '-', '-', '-', '-', '-', '-', '-')));
board.add(new ArrayList<>(Arrays.asList('-', 'P', '-', '-', '-', '-', 'p', '-')));
board.add(new ArrayList<>(Arrays.asList('-', '-', '-', '-', '-', 'p', '-', '-')));
board.add(new ArrayList<>(Arrays.asList('-', '-', '-', '-', '-', '-', '-', '-')));
board.add(new ArrayList<>(Arrays.asList('p', '-', '-', '-', 'b', '-', '-', 'q')));
board.add(new ArrayList<>(Arrays.asList('-', '-', '-', '-', 'n', '-', '-', 'k')));
initialise();
initTable();
int hashValue = computeHash(board);
System.out.println("The hash value is : " + hashValue);
// Move the white king to the left
char piece = board.get(0).get(3);
board.get(0).set(3, '-');
hashValue ^= ZobristTable.get(0).get(3).get(indexOf(piece));
board.get(0).set(2, piece);
hashValue ^= ZobristTable.get(0).get(2).get(indexOf(piece));
System.out.println("The new hash value is : " + hashValue);
// Undo the white king move
piece = board.get(0).get(2);
board.get(0).set(2, '-');
hashValue ^= ZobristTable.get(0).get(2).get(indexOf(piece));
board.get(0).set(3, piece);
hashValue ^= ZobristTable.get(0).get(3).get(indexOf(piece));
System.out.println("The new hash value is : " + hashValue);
}
}
// This code is contributed by Vaibhav