When a chess engine sees a position p repeated once (i.e. position p occurred twice) it immediately assigns the second occurrence of position p a draw score. This makes sense because position p doesn't need to occur thrice in order for the chess engine to realize that it's not making progress (i.e. a twofold repetition is just as drawn as a threefold repetition).
Many chess engines do just this. They assign a draw score to all twofold repetitions. However, some of the best chess engines such as Stockfish and Ethereal don't assign a draw score to all twofold repetitions. If the first occurrence of position p is not strictly after the root node then they don't assign a draw score to the twofold repetition. Instead, the position needs to be repeated twice (i.e. it needs to be a threefold repetition) in order for it to be assigned a draw score.
For example, consider the following drawnByRepetition
function from the Ethereal source code:
int drawnByRepetition(Board *board, int height) {
int reps = 0;
// Look through hash histories for our moves
for (int i = board->numMoves - 2; i >= 0; i -= 2) {
// No draw can occur before a zeroing move
if (i < board->numMoves - board->fiftyMoveRule)
break;
// Check for matching hash with a two fold after the root,
// or a three fold which occurs in part before the root move
if ( board->history[i] == board->hash
&& (i > board->numMoves - height || ++reps == 2))
return 1;
}
return 0;
}
As you can see either i
must be greater than the root node (i.e. it must come after the root node) or the position p needs to be repeated twice (i.e. it must be a threefold repetition) for it to be assigned a draw score.
The chess programming wiki has the following to say about assigning draw score to repetitions:
Threefold repetition implies a position occurred thrice, that is repeated twice. When to score the position as a draw, however, is an entirely different matter. Most programs do this on the first repetition, no matter whether the first occurrence of the repeated position appears in the current search space, or not. Other programs consider that fact, they avoid cycles inside the current search tree to make it a directed acyclic graph (DAG), but allow a one-fold repetition, if the first occurrence appears in the game history before the current root. Anyway, to wait for the second repetition one has its pros and cons. The Repetition score is either zero or the contempt factor.
It says that “to wait for the second repetition one has its pros and cons.” So, what exactly are the pros and cons? I couldn't find an explanation as to why top chess engines like Stockfish and Ethereal do this.