Triggered by the suggestion a week or so ago that my hashing code was broken I took a look at my chess-engine (which is different from the book generation code).
In the transpositiontable-code I added two counters; hits and collisions. A hit is increased if tt[hash % n] == hash, collisions if != hash.
To my surprise I still get over 15% collisions. That is with ~7 plies search depth. Earlier today that was over 35% by the way: I had forgotten to replace the rand() by something better (I now read a uint64_t from /dev/urandom).
Maybe you guys can spot the problem?
init
Code: Select all
for(int pos=0; pos<64; pos++) {
for(int type=0; type<6 * 2; type++)
zobristPieceAtLoc[type][pos] = temp[ti++];
}
zobristIsWhite = temp[ti++];
for(int i=0; i<4; i++)
zobristCastling[i] = temp[ti++];
for(int i=0; i<8; i++)
zobristEnPassant[i] = temp[ti++];
lookup
Code: Select all
tptEntry Tpt::lookup(const uint64_t hash)
{
unsigned long int index = hash % nEntries;
tptEntry copy = invalid;
if (entries[index].hash == hash)
copy = entries[index];
return copy;
}
Code: Select all
void Tpt::store(const uint64_t hash, const tptEntryFlag f, const int d, const int value)
{
unsigned long int index = hash % nEntries;
entries[index].hash = hash;
entries[index].value = (int16_t)value;
entries[index].depth = (int8_t)d; // FIXME uint8_t?
entries[index].flags = (int8_t)f;
}
hashing
Code: Select all
uint64_t Tpt::calcZobrist(const Board * const b, const PlayerColor c, const Move *const epMove)
{
uint64_t hash = 0;
if (c == WHITE)
hash ^= zobristIsWhite;
for(int y=0; y<8; y++) {
int offset = y * 8;
for(int x=0; x<8; x++, offset++) {
const ChessPiece *const cur = b -> getAt(x, y);
// getType() returns 0...5
if (cur != NULL)
hash ^= zobristPieceAtLoc[cur -> getType() + (cur -> getColor() == BLACK ? 6 : 0) ][offset];
}
}
// white king first move
if (b -> getAt(4, 0) && b -> getAt(4, 0) -> getFirstMove())
{
// left rook
if (b -> getAt(0, 0) && b -> getAt(0, 0) -> getFirstMove())
hash ^= zobristCastling[0];
// right rook
if (b -> getAt(7, 0) && b -> getAt(7, 0) -> getFirstMove())
hash ^= zobristCastling[1];
}
if (b -> getAt(4, 7) && b -> getAt(4, 7) -> getFirstMove())
{
if (b -> getAt(0, 7) && b -> getAt(0, 7) -> getFirstMove())
hash ^= zobristCastling[2];
if (b -> getAt(7, 7) && b -> getAt(7, 7) -> getFirstMove())
hash ^= zobristCastling[3];
}
if (epMove)
hash ^= zobristEnPassant[epMove -> tx];
return hash;
}