So I finally finished the complete rewrite of my engine, and I am getting pretty good results.
Yesterday I was adding various debug prints in the code of the engine, to mesure the metrics of the code. In particular I was concentrating on the Transposition Table, since I had a feeling there may have been problems with it, since I still can't solve Fine#70.
Now in my code, I have this part of the negamax routine:
Code: Select all
// Step 3: TT probe
Score ttScore = -infinity;
Move ttMove = 0;
U8 ttFlag = 255;
ttEntry* entry = fetchTT(pos.hashKey);
if (entry) {
ttScore = entry->score;
ttMove = entry->bestMove;
ttFlag = entry->flags;
// Account for mate values
ttScore += ply * (ttScore < -mateValue);
ttScore -= ply * (ttScore > mateValue);
// Only return value in non pv nodes
if (!pvNode) {
if (tt->depth >= depth ) {
Score toRet = -infinity;
if (ttFlag == hashEXACT) toRet = ttScore;
if (ttFlag == hashALPHA && ttScore <= alpha) toRet = alpha;
if (ttFlag == hashBETA && ttScore >= beta) toRet = beta;
if (toRet != -infinity) {
// Update scores as if we did find the move through a normal search
if (ttScore >= beta) {
killerTable[1][ply] = killerTable[0][ply];
killerTable[0][ply] = ttMove;
counterMoveTable[movePiece(pos.lastMove)][moveTarget(pos.lastMove)] = ttMove;
}
else if (ttScore >= alpha) {
historyTable[pos.side][moveSource(ttMove)][moveTarget(ttMove)] += ((int)depth * (int)depth) / 2;
localHistory[ply][moveSource(ttMove)][moveTarget(ttMove)] += ((int)depth * (int)depth) / 2;
}
return toRet;
}
}
}
}
Code: Select all
ttEntry *fetchTT(HashKey key){
ttEntry *entry = &tt[key % ttSize];
if (entry->hashKey == key) return entry;
return 0;
}
Code: Select all
(tt->depth >= depth )
Now that is, I think, not a normal behaviour.
So I tried doing a depth 18 search on startposition. I then read the depth from every entry from the transposition table and, to my horror, every entry had depth 0.
I don't know what the problem can be.
My tt entry structure is fairly simple:
Code: Select all
struct ttEntry {
HashKey hashKey;
U16 bestMove;
Depth depth;
U8 flags = 3;
Score score = -infinity;
};
The replacement scheme is the following:
- If the entry has the same hashKey replace when new depth is greater or equl to the one in the ttEntry
- If the entry doesn't have the same hashKey (different position), replace when (where depth is the new depth and flags is the new flag).
Code: Select all
entry->depth <= depth + 2 * (flags == hashEXACT)
The hashKey generation works, having passed a 6300+ positions perft suite with the generated hashKey checked against the incrementally updated, I also made the engine play 100 matches at 1 second per move from book positions with the same check, and there seems to be no problem.
What could it be?
Has anyone ever had this kind of problem?
Will I be able to solve Fine#70 before I die?
Thanks in advance for all the responses.