Implementing Zobrist hashing in Javascript

南楼画角 提交于 2019-12-24 18:01:22

问题


I need to implement Zobrist hashing for a chess engine in Javascript and I'm wondering what is the best way of accomplishing this. Now, I'm not a computer scientist and never had formal algorithms and data structures classes so I'm sorry if I'm a bit off on this...

From what I understand I need a 64 bit hashfunction to encode a position as lower than that originates too many collisions. Now in javascript I only have access to 32 bits numbers. Also there is an issue with how I implement the hash table and how it gets implemented "behind the scenes" by the V8 engine in node.

I can either have it as a javascript array of length TABLESIZE and do something like:

var table = new Array();

table[hashCodeLo % TABLESIZE] = {
    hashCodeLo: hashCodeLo,
    hashCodeHi: hashCodeHi,
    someProperty: someValue
};

where hashCodeLo and hashCodeHi denote the higher and lower 32 bits of the code and TABLESIZE < 2^32. I store these to detect collisions from doing the % TABLESIZE bit. Now I'm guessing since TABLESIZE is large and I'm assigning elements non contiguously V8 will kick this into "dictionary mode" anyways so I might as well not bother making it an array indexed by an integer up to TABLESIZE and instead do something like:

var table = {};

table[hashCode] = {
    someProperty: someValue
}

where here hashCode is just a string representation of my 64 bits hashCode. Since I'm not sure how "dictionary mode" works behind the scenes I'm not sure which is better. Also I don't know if I'm using more memory by using keys like '1983981918391' vs a more compact representation like:

hashCode = String.fromCharCode(FIRST_16BITS, SECOND_16BITS, THIRD_16BITS, FOURTH_16BITS)

I'm not even sure if this works the way I intend...

Since this is a critical part of the engine I want to squeeze as much performance as I can out of this so any help is appreciated.


回答1:


From what I understand I need a 64 bit hashfunction to encode a position as lower than that originates too many collisions.

Not for the transposition table at least - it will hardly have a size of 264.

If you're implementing this to encode the positions themselves (and detect some of the collisions by comparing the 64-bit hash), then yes you can use 64 bits if that is what literature recommends (though you might want to try 52 bits as well).

Now in javascript I only have access to 32 bits numbers.

No. Numbers in JavaScript are 64-bit floats, and you can store up to 52-bit integers in them precisely. Only the bitwise operators are limited to 32-bit integers (to whom the numbers will be casted if necessary).

However, arrays themselves are limited to a length of 232; yet even this should be more than enough.

Also there is an issue with how I implement the hash table and how it gets implemented "behind the scenes" by the V8 engine in node.

Just implement is as an array. Try to fill it with null values for initialisation and see whether a non-sparse array performs better. If you care about performance, test it.

hashCodeLo and hashCodeHi denote the higher and lower 32 bits of the code and TABLESIZE < 2^32. I store these to detect collisions

I'd use a Uint32Array instead of an array of objects. Depending on what someProperty and someValue are, you might want to just store an index of an object in a normal array, or a scalar itself (possibly using a DataView). The code might look like this:

var zobrist = new Uint32Array(13 * 2 * 64 * 2) // pieces * colors * fields * 64/32
for (var i=0; i<zobrist.length; i++)
    zobrist[i] = Math.random() * 4294967296;

var table = new Uint32Array(3 * tablesize);

function hash(hi, lo, piece, color, field) {
    hi ^= zobrist[piece * 128 + color * 64 + field];
    lo ^= zobrist[piece * 128 + color * 64 + field + 1];

    var i = lo % tablesize;
    if (table[i] == hi && table[i+1] == lo) {
        // collision
    } else {
        table[i] = hi; table[i+1] = lo;
        // do what you want with table[i+2]
    }
}


来源:https://stackoverflow.com/questions/24813487/implementing-zobrist-hashing-in-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!