Answers.Body: <p>Looking at some of the forum discussions at the end of the linked chessprogramming.org page, you can see some of the rationale for waiting for the third repetition to consider a position drawn if the first occurrence of the position was before the root.</p>
  <p><a href="https://www.stmintz.com/ccc/index.php?id=47672" rel="nofollow noreferrer">https://www.stmintz.com/ccc/index.php?id=47672</a></p>
  <blockquote>
  <p>My program was playing a game against Greg Kennedy a long time ago, and the
  following situation occurred.</p>
  <p>The program was down two pawns and was completely lost.  But Kennedy made a
  mistake, and my program made a move that won a pawn.  At this point the best
  move from Kennedy's point of view was to undo the move he'd just done. My program's move forced him off of something he was defending, and he had to go
  back to where he was, and now the program could simply take a pawn that was sitting there for free, vastly improve its chances for a draw.</p>
  <p>But that's not what it did.  The move it made to win the pawn was also retractable, so it chose to repeat the position, and scored this as 0.00.</p>
  <p>Of course, rather than repeating his mistake, Kennedy chose a better move and my program was down two pawns again.</p>
  </blockquote>
  <p>I think this one exemplifies the situation best. In the search, the program assumes that both sides will play the position perfectly. However, this is not the case in real life, especially when a human is involved. As such, reaching a certain position in the past may have been a mistake that should be avoided, and the opponent would likely avoid making that same mistake again if given the opportunity. If the search considers a position drawn on the first repetition, irrespective of whether the position was first reached in the actual game history or in the search, it could miss that the position is actually bad for the opponent and that they would avoid the second repetition.</p>
  <p>However, if the repeated position first occurs in the search tree, then it should be safe to assume it as drawn on the first repeat. The search assumes perfect play, so if the first occurrence of the position was not a mistake, and repeating it once is also not a mistake, then three times would not be a mistake either. Perfect play would thus continue on and bring us back to the same position ad infinitum were it not for the three-fold repetition rule.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-04-25T14:56:25.587Z
Answers.LastActivityDate: 2023-04-25T14:56:25.587Z
Answers.UserDisplayName: Nelson O
Answers.Body: <blockquote>
    <p>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.</p>
  </blockquote>
  
  <p>My discussion will be technical, so let's make it as simple as possible. Firstly, let's make be clear about this:</p>
  
  <blockquote>
    <p>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.</p>
  </blockquote>
  
  <p>Why would an engine do that? Let's consider <strong>two scenarios</strong> 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.</p>
  
  <ul>
  <li>The position repeated and played on the board, for example, the position occurred on move 24th and 26th.</li>
  <li>The position <strong>never</strong> actually played on the board, but it is part of the search. The position occurred at move 35th. (IMPORTANT - only a single repetition)</li>
  </ul>
  
  <p><strong>Scenario 1</strong></p>
  
  <p>In the first scenario, it's a repetition that we all understand. In your code example:</p>
  
  <pre><code>++reps == 2 
  </code></pre>
  
  <p>So, if a position repeated twice earlier in the game <strong>before</strong> the root (root == current board position), it's a three-fold repetition. Very simple.</p>
  
  <p><strong>Scenario 2</strong></p>
  
  <p>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.</p>
  
  <p>Your code example:</p>
  
  <pre><code>i &gt; board-&gt;numMoves - height
  </code></pre>
  
  <blockquote>
    <p>So, what exactly are the pros and cons?</p>
  </blockquote>
  
  <p>Pros: search quicker and deeper</p>
  
  <p>Cons: you assume the same position would occur again later in the search (e.g. move 45th), which is not always true</p>
  
  <blockquote>
    <p>I couldn't find an explanation as to why top chess engines like Stockfish and Ethereal do this.</p>
  </blockquote>
  
  <p>Search quicker and deeper. Common optimization in modern chess programming.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-10-14T21:02:40.513Z
Answers.Text: 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?
Answers.UserDisplayName: Aadit M Shah
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-10-15T02:31:23.373Z
Answers.Text: @AaditMShah we would assign a draw score in this case including your code example
Answers.UserDisplayName: SmallChess
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-10-15T22:44:25.470Z
Answers.Text: 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.
Answers.UserDisplayName: Aadit M Shah
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-10-16T01:34:42.043Z
Answers.Text: @AaditMShah  we would as soon as we see the first repetition after the root
Answers.UserDisplayName: SmallChess
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-10-16T05:20:22.757Z
Answers.Text: 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.
Answers.UserDisplayName: Aadit M Shah
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-10-14T15:44:38.073Z
Answers.LastActivityDate: 2018-10-14T15:50:00.670Z
Answers.LastEditDate: 2018-10-14T15:50:00.670Z
Answers.UserDisplayName: SmallChess
Answers.Body: <p>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, <em>not</em> an automatic draw to repeat the position once.</p>
  
  <p>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.  </p>
  
  <p>So, which scenario is more likely?</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2018-10-14T14:48:48.047Z
Answers.LastActivityDate: 2018-10-14T14:48:48.047Z
Answers.UserDisplayName: D M
Body: <p>When a chess engine sees a position <em>p</em> repeated once (i.e. position <em>p</em> occurred twice) it immediately assigns the second occurrence of position <em>p</em> a draw score. This makes sense because position <em>p</em> 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).</p>
  
  <p>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 <em>p</em> 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.</p>
  
  <p>For example, consider the following <a href="https://github.com/AndyGrant/Ethereal/blob/10a2c2f9cf2dfc0f4a3d172037bb6003bb1074e3/src/board.c#L316-L335" rel="noreferrer"><code>drawnByRepetition</code></a> function from the Ethereal source code:</p>
  
  
  
  <pre><code>int drawnByRepetition(Board *board, int height) {
  
      int reps = 0;
  
      // Look through hash histories for our moves
      for (int i = board-&gt;numMoves - 2; i &gt;= 0; i -= 2) {
  
          // No draw can occur before a zeroing move
          if (i &lt; board-&gt;numMoves - board-&gt;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-&gt;history[i] == board-&gt;hash
              &amp;&amp; (i &gt; board-&gt;numMoves - height || ++reps == 2))
              return 1;
      }
  
      return 0;
  }
  </code></pre>
  
  <p>As you can see either <code>i</code> must be greater than the root node (i.e. it must come after the root node) or the position <em>p</em> needs to be repeated twice (i.e. it must be a threefold repetition) for it to be assigned a draw score.</p>
  
  <p>The chess programming wiki has the following to say about <a href="https://www.chessprogramming.org/Repetitions#Assigning_Draw_Score" rel="noreferrer">assigning draw score</a> to repetitions:</p>
  
  <blockquote>
    <p>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 <a href="https://en.wikipedia.org/wiki/Cycle_%28graph_theory%29" rel="noreferrer">cycles</a> inside the current <a href="https://www.chessprogramming.org/Search_Tree" rel="noreferrer">search tree</a> to make it a <a href="https://en.wikipedia.org/wiki/Directed_acyclic_graph" rel="noreferrer">directed acyclic graph</a> (DAG), but allow a one-fold repetition, if the first occurrence appears in the game history before the current <a href="https://www.chessprogramming.org/Root" rel="noreferrer">root</a>. Anyway, to wait for the second repetition one has its pros and cons. The Repetition score is either zero or the <a href="https://www.chessprogramming.org/Contempt_Factor" rel="noreferrer">contempt factor</a>.</p>
  </blockquote>
  
  <p>It says that &ldquo;to wait for the second repetition one has its pros and cons.&rdquo; 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.</p>
  
Tags: <engines><stockfish><programming><draw><threefold-repetition>
Title: What's the rationale behind chess engines conditionally allowing threefold repetitions when assigning a draw score?
ThreadText: # What's the rationale behind chess engines conditionally allowing threefold repetitions when assigning a draw score?
  
  (Asked by: username_0 on 2018-10-14)
  
  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`](https://github.com/AndyGrant/Ethereal/blob/10a2c2f9cf2dfc0f4a3d172037bb6003bb1074e3/src/board.c#L316-L335) 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](https://www.chessprogramming.org/Repetitions#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](https://en.wikipedia.org/wiki/Cycle_%28graph_theory%29) inside the current [search tree](https://www.chessprogramming.org/Search_Tree) to make it a [directed acyclic graph](https://en.wikipedia.org/wiki/Directed_acyclic_graph) (DAG), but allow a one-fold repetition, if the first occurrence appears in the game history before the current [root](https://www.chessprogramming.org/Root). Anyway, to wait for the second repetition one has its pros and cons. The Repetition score is either zero or the [contempt factor](https://www.chessprogramming.org/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.
  
  **Tags:** engines, stockfish, programming, draw, threefold-repetition
  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_1 on 2023-04-25. Score: 2
  
  Looking at some of the forum discussions at the end of the linked chessprogramming.org page, you can see some of the rationale for waiting for the third repetition to consider a position drawn if the first occurrence of the position was before the root.
  
  <https://www.stmintz.com/ccc/index.php?id=47672>
  
  > My program was playing a game against Greg Kennedy a long time ago, and the
  > following situation occurred.
  >
  > The program was down two pawns and was completely lost. But Kennedy made a
  > mistake, and my program made a move that won a pawn. At this point the best
  > move from Kennedy's point of view was to undo the move he'd just done. My program's move forced him off of something he was defending, and he had to go
  > back to where he was, and now the program could simply take a pawn that was sitting there for free, vastly improve its chances for a draw.
  >
  > But that's not what it did. The move it made to win the pawn was also retractable, so it chose to repeat the position, and scored this as 0.00.
  >
  > Of course, rather than repeating his mistake, Kennedy chose a better move and my program was down two pawns again.
  
  I think this one exemplifies the situation best. In the search, the program assumes that both sides will play the position perfectly. However, this is not the case in real life, especially when a human is involved. As such, reaching a certain position in the past may have been a mistake that should be avoided, and the opponent would likely avoid making that same mistake again if given the opportunity. If the search considers a position drawn on the first repetition, irrespective of whether the position was first reached in the actual game history or in the search, it could miss that the position is actually bad for the opponent and that they would avoid the second repetition.
  
  However, if the repeated position first occurs in the search tree, then it should be safe to assume it as drawn on the first repeat. The search assumes perfect play, so if the first occurrence of the position was not a mistake, and repeating it once is also not a mistake, then three times would not be a mistake either. Perfect play would thus continue on and bring us back to the same position ad infinitum were it not for the three-fold repetition rule.
  
  
  ---
  
  ### Answer by username_2 on 2018-10-14. Score: 2
  
  > 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.
  
  Your code example:
  
  ```
  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.
  
  > **Comments:**
  > **username_0**: 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?  
  > **username_2**: @username_0 we would assign a draw score in this case including your code example  
  > **username_0**: 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.  
  > **username_2**: @username_0  we would as soon as we see the first repetition after the root  
  > **username_0**: 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.  
  
  ---
  
  ### Answer by username_3 on 2018-10-14. Score: -2
  
  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?
  
  
  ---
  
  