0

I'm trying to implement Zobrist hashing for a chess game and thought I was doing things correctly. However, when I try to apply XOR to a Hash value, it simply changes between 0 (the starting value for the hash) and -2147483648, in spite of conducting a bitwise XOR against a random number between 0 and 18446744073709551616.

Here's some code. I thought it was relatively simple with a struct for each entry in the Grid, a constructor function to make an entry, a function to create the Hash Table, and finally one for the Hash itself.

//Hash Table struct. This can be expanded for each new piece type
HashTableEntry = {
    QueenHash:-1,
    BishopHash:-1,
    KnightHash:-1,
    RookHash:-1,
    PawnHash:-1,
    KingHash:-1
};

//A function for creating a Hash Table Entry
function toHashTableEntryStruct() constructor {
    var HashUpperBound = 18446744073709551616;
    
    QueenHash = random(HashUpperBound);
    BishopHash = random(HashUpperBound);
    KnightHash = random(HashUpperBound);
    RookHash = random(HashUpperBound);
    PawnHash = random(HashUpperBound);
    KingHash = random(HashUpperBound);

}

//A function to create a ds_grid Hash Table of the size passed to it, which it then returns
function CreateHashTable(_width, _height){
    //Copy the local variables
    var width = _width;
    var height = _height;
    //Create the grid for the Hash Table
    var NewHashTable = ds_grid_create(width, height);

    //Copy the original seed and set the game's seed to create the same table each time
    var OriginalSeed = random_get_seed;
    random_set_seed(280804);

    //Loop through the Grid and fill each value with a HashTableEntry struct
    for(var i = 0; i < width; i++;){
        for(var j = 0; j < height; j++;){
            var NewHash = new toHashTableEntryStruct();
            ds_grid_set(NewHashTable, i, j, NewHash);
        }
    }

    //Reset the seed
    random_set_seed(OriginalSeed);
    //Return the shiny new Hash Table
    return NewHashTable;
}

//A function for creating the original Hash of a board. This should only be called on 
initialising a Board as it sets the Original Hash
function CreateBoardHash(_board){
    var Board = _board;
    var width = ds_grid_width(Board);
    var height = ds_grid_height(Board);
    HashTable = CreateHashTable(width, height);
    var FinalHash = 0;

    for(var i = 0; i < width; i++;){
        for(var j = 0; j < height; j++;){
            var PieceToCheck = ds_grid_get(Board, i, j);
            if(PieceToCheck == Pieces.BLANK){ continue; }
            var HashEntry = ds_grid_get(HashTable, i, j);
            var XorValue = MatchPieceToHashTableEntry(PieceToCheck, HashEntry);
            FinalHash ^= XorValue;
        }
    }

    if(FinalHash == 0){
        //Error here
        return;
    }

    //Set the instance variable for this original Hash
    OriginalHash = FinalHash;
    //Add it to the Current Hash stack
    CurrentHash = FinalHash;

    //Return said hash for the calling function
    return FinalHash;
}

The problem comes in the FinalHash ^= XorValue; line, where XorValue each time is a random number, but FinalHash only ever comes out as 0 or -2147483648.

Can someone help with why this is the case and what I may be doing wrong with my XOR function?

1 Answers1

0

Thanks to Reddit, I have fixed this. GameMaker must be doing something weird with the ^= operator, as the solution was as follows:

FinalHash = FinalHash ^ XorValue;