Back to your last example:
[d]1k3r2/1P5R/6p1/4p3/6PP/8/P4b2/1R5K b - - 1 1
Some definitions:
After 1...e4 position P1 is reached for the first time: P1(1).
After 2.Rb5 Ba7 3.Rb1 Bf2, position P1 is reached for the second time: P1(2).
After playing 4. Rb5 Ba7 5.Rb1 Bf2, position P1 is reached for the third time: P1(3).
A)
P1(3) is a draw by FIDE rules. When reached during the game, both the GUI and the engine's game playing code should detect it as a three-fold repetition and handle it according to the rules (usually the game will end there).
B)
Now let's look at the case where the root of your search is somewhere on the path between P1(1) and P1(2), including the former but excluding the latter. At some point the search will reach P1(2). Since this is neither a two-fold rep during search nor a three-fold rep during the game, a normal subtree search will be performed, eventually returning a score which is then stored in the TT. That may be subject of your trouble but it should not be, see below!
If that search of P1(2) is deep enough it will also visit P1(3), detect it as first repetition during search (and second during game as well), and score it as a draw without further search. Repetition detection always goes first, so TT is not used here, i.e. no probing (reading) and also nothing to store. That draw score may or may not affect the search score of P1(2) (see previous paragraph of case B) in general. In the given position White should be winning, though, so P1(3) should not affect the PV of P1(2).
C)
Last case is when the root of your search is somewhere on the path between P1(2) and P1(3), again including the former but excluding the latter. At some point the search will reach P1(3). What happens? Well, it is as simple as the other cases: you always do the repetition detection first, no TT probing yet. So you find out that the current position does not repeat a tree position but it repeats a game position that had already been repeated => three-fold rep detected, return draw score. TT unused again.
Here is my repetition detection pseudo code:
Code: Select all
bool isRepetition(bool isRoot)
{
int ply = currentPly();
int stop = std::max<int>(ply - fifty(), 0);
for (int i = ply - 4; i >= stop; i -= 2) {
if (position[i].hashKey == currentHashKey()) {
position[ply].nRepetitions = position[i].nRepetitions + 1;
return position[ply].nRepetitions >= 2 || !isRoot;
}
}
}