# What's the rationale behind chess engines conditionally allowing threefold repetitions when assigning a draw score?

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.

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.

My discussion will be technical, so let's make it as simple as possible. Firstly, let's make be clear about this:

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.

Why would an engine do that? Let's consider two scenarios where we have three-fold repetition during the search. Let's assume we are on move 30th, and the engine is thinking at move 40th.

• The position repeated and played on the board, for example, the position occurred on move 24th and 26th.
• The position never actually played on the board, but it is part of the search. The position occurred at move 35th. (IMPORTANT - only a single repetition)

Scenario 1

In the first scenario, it's a repetition that we all understand. In your code example:

``````++reps == 2
``````

So, if a position repeated twice earlier in the game before the root (root == current board position), it's a three-fold repetition. Very simple.

Scenario 2

What about the second scenario? You have the identical position on move 35th, and the same position come back on move 40th. Thus, it's reasonable to assume if you search further you will encounter the position again (for the third repetition). For example, move 45th.

``````i > board->numMoves - height
``````

So, what exactly are the pros and cons?

Pros: search quicker and deeper

Cons: you assume the same position would occur again later in the search (e.g. move 45th), which is not always true

I couldn't find an explanation as to why top chess engines like Stockfish and Ethereal do this.

Search quicker and deeper. Common optimization in modern chess programming.

• Right, but I'm more interested in the case where a position occurs twice, once before the current root (say at move 24) and once after the current root (say at move 40), where the current root is move 30. In this case, we won't assign a draw score because 24 is lesser than 30 and the position has only been repeated once. My question is why would you not want to assign a draw score to the position at move 40 in this case? Oct 14 '18 at 21:02
• @AaditMShah we would assign a draw score in this case including your code example Oct 15 '18 at 2:31
• Actually, we wouldn't. It's not a threefold repetition and the first occurrence was before the root node. Thus, we don't assign it a draw score. Hence the question. Oct 15 '18 at 22:44
• @AaditMShah we would as soon as we see the first repetition after the root Oct 16 '18 at 1:34
• Actually, because of the order in which we check the positions (i.e. from most recent to least recent) if we don't see a position after the root only then do we check for repetitions. Oct 16 '18 at 5:20

Let's say your engine sees the best moves in a position as +0.08 and +0.06. It plays the +0.08 move and the opponent replies. In the new position, the engine realizes that it was slightly optimistic, and the best continuation is now +0.01 unless it repeats the position. I think it makes more sense for it to evaluate the repetition as +0.06 than a flat 0. It is, after all, not an automatic draw to repeat the position once.

It is, of course, very possible that after the engine repeats and plays the +0.06 move, it will again find that it was optimistic (perhaps for the same general reason) and now the best move is -0.01. Perhaps it now missed its chance to get the +0.01.

So, which scenario is more likely?