0

我正在尝试为国际象棋游戏实现 Zobrist 散列,并认为我做的事情是正确的。但是,当我尝试对哈希值应用 XOR 时,它只是在 0(哈希的起始值)和 -2147483648 之间变化,尽管对 0 到 18446744073709551616 之间的随机数进行按位 XOR。

这是一些代码。我认为它相对简单,网格中的每个条目都有一个结构,一个用于创建条目的构造函数,一个创建哈希表的函数,最后一个用于哈希本身。

//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;
}

问题出在 FinalHash ^= XorValue; 行,其中 XorValue 每次都是一个随机数,但 FinalHash 只会以 0 或 -2147483648 的形式出现。

有人可以帮助解释为什么会这样以及我的 XOR 函数可能做错了什么吗?

4

1 回答 1

0

感谢 Reddit,我已经解决了这个问题。GameMaker 一定是在用 ^= 运算符做一些奇怪的事情,因为解决方案如下:

FinalHash = FinalHash ^ XorValue;
于 2021-03-25T22:56:24.283 回答