Answers.Body: <p>No. You <strong>shouldn't</strong> count null-move in repetitions because:</p>
  
  <ul>
  <li>Null-move is fake</li>
  <li>Null-move artificially creates a repetition when there is none</li>
  </ul>
  
  <p>Your implementation is correct, but you might want to exclude null-move. Let's take a look at Stockfish:</p>
  
  <blockquote>
    <p><a href="https://github.com/official-stockfish/Stockfish/blob/master/src/position.cpp" rel="nofollow noreferrer">https://github.com/official-stockfish/Stockfish/blob/master/src/position.cpp</a></p>
  </blockquote>
  
  <pre><code>bool Position::is_draw(int ply) const {
  
    if (st-&gt;rule50 &gt; 99 &amp;&amp; (!checkers() || MoveList&lt;LEGAL&gt;(*this).size()))
        return true;
  
    int end = std::min(st-&gt;rule50, st-&gt;pliesFromNull);
  
    if (end &lt; 4)
      return false;
  
    StateInfo* stp = st-&gt;previous-&gt;previous;
    int cnt = 0;
  
    for (int i = 4; i &lt;= end; i += 2)
    {
        stp = stp-&gt;previous-&gt;previous;
  
        // At root position ply is 1, so return a draw score if a position
        // repeats once earlier but after or at the root, or repeats twice
        // strictly before the root.
        if (   stp-&gt;key == st-&gt;key
            &amp;&amp; ++cnt + (ply - i &gt; 0) == 2)
            return true;
    }
  
    return false;
  }
  </code></pre>
  
  <p>You already have <code>st-&gt;rule50</code> in your code (<code>board-&gt;fifty-move</code>) but you don't have <code>st-&gt;pliesFromNull</code>.</p>
  
  <p>Let's check what Stockfish author said about <code>pilesFromNull</code>.</p>
  
  <blockquote>
    <p><a href="http://www.talkchess.com/forum/viewtopic.php?start=0&amp;t=35052&amp;topic_view=flat&amp;sid=46a5561bcd0c4d36796c0fbfe5158079" rel="nofollow noreferrer">http://www.talkchess.com/forum/viewtopic.php?start=0&amp;t=35052&amp;topic_view=flat&amp;sid=46a5561bcd0c4d36796c0fbfe5158079</a></p>
  </blockquote>
  
  <p>By Joona Kiiski (2010):</p>
  
  <pre><code>They are already excluded, note the use of st-&gt;pliesFromNull: 
  
  Null moves can artificially create a repetition 
  draw where instead there is no one. 
  
  So use a second counter to reset history after a null move. 
  </code></pre>
  
  <p>You see, if the strongest engine in the world does it you have no reason for not doing it.</p>
  
  <p>If you check the code carefully, the first time when you do a null-move <code>pliesFromNull</code> is 0.</p>
  
  <pre><code>void Position::do_null_move(StateInfo&amp; newSt) {
      ....
      st-&gt;pliesFromNull = 0;
  }
  </code></pre>
  
  <p>later the engine increments the counter in <code>do_move</code>:</p>
  
  <pre><code>++st-&gt;pliesFromNull;
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-05-04T02:53:19.883Z
Answers.LastActivityDate: 2017-05-04T03:48:25.933Z
Answers.LastEditDate: 2017-05-04T03:48:25.933Z
Answers.UserDisplayName: SmallChess
Body: <p>Added transposition table (this was tested alone and worked as expected), three fold repetition and null move pruning in my engine and wins more games but some of them end with three fold repetition even in win positions, played against the previous version</p>
  
  <p>I keep a table history to save the current state of the board before making the move, to save the current zobrist key, move, en passant and castling</p>
  
  <p>In make null function I just hash the en passant if exists, switch side, hash it and increment the fiftymove counter </p>
  
  <p>To check for repetitions I do this:</p>
  
  <pre><code>int i;
  for (i = 4; i &lt;= board-&gt;fiifty_move; i += 2) {
      if (board-&gt;zkey == board-&gt;history[board-&gt;ply - i].zkey) {
          return true;
      }
  }
  </code></pre>
  
  <p>The question is when checking for repetition it will check also for null move positions, is that correct? If a null move is repeated can we take that as a move even that null move it just switching sides?</p>
  
  <p>I've seen engines that has a array like: <code>hist_rep[index++].zkey = curr_zkey;</code> that is only to check for repetitions and the array is not filled in the make null move function</p>
  
  <p>Others engines has a counter inside the repetition function to check if the position has been repeated before more than one time</p>
  
  <pre><code>for (...) {
      if (zkey[i] == curr_zkey) ++rep;
      if (rep == 2) return true;
  }
  </code></pre>
  
  <p>What is the correct way?</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-04-27T22:15:11.717Z
Comments.Text: This question is about programming not chess. Try stackoverflow.
Comments.UserDisplayName: Brian Towers
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-04-27T22:41:54.153Z
Comments.Text: @BrianTowers chess engine programming questions are on-topic here.
Comments.UserDisplayName: Herb
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-04-28T01:37:42.360Z
Comments.Text: I'd argue against closing the question. This is on-topic and it talks about chess programming. The question is not about how to write a loop in C++. Discussing about chess here is reasonable. Try not to make our site worse, we don't have enough questions (https://chess.meta.stackexchange.com/questions/476/any-possibility-for-chess-to-graduate?cb=1)
Comments.UserDisplayName: SmallChess
Tags: <engines><programming><transpositions><threefold-repetition>
Title: Three-fold repetition and null move
ThreadText: # Three-fold repetition and null move
  
  (Asked by: username_0 on 2017-04-27)
  
  Added transposition table (this was tested alone and worked as expected), three fold repetition and null move pruning in my engine and wins more games but some of them end with three fold repetition even in win positions, played against the previous version
  I keep a table history to save the current state of the board before making the move, to save the current zobrist key, move, en passant and castling
  In make null function I just hash the en passant if exists, switch side, hash it and increment the fiftymove counter 
  To check for repetitions I do this:
  int i;
  for (i = 4; i <= board->fiifty_move; i += 2) {
      if (board->zkey == board->history[board->ply - i].zkey) {
          return true;
      }
  }
  
  The question is when checking for repetition it will check also for null move positions, is that correct? If a null move is repeated can we take that as a move even that null move it just switching sides?
  I've seen engines that has a array like: hist_rep[index++].zkey = curr_zkey; that is only to check for repetitions and the array is not filled in the make null move function
  Others engines has a counter inside the repetition function to check if the position has been repeated before more than one time
  for (...) {
      if (zkey[i] == curr_zkey) ++rep;
      if (rep == 2) return true;
  }
  
  What is the correct way?
  
  **Tags:** engines, programming, transpositions, threefold-repetition
  
  > **Comments:**
  > **username_1**: This question is about programming not chess. Try stackoverflow.  
  > **username_2**: @BrianTowers chess engine programming questions are on-topic here.  
  > **username_3**: I'd argue against closing the question. This is on-topic and it talks about chess programming. The question is not about how to write a loop in C++. Discussing about chess here is reasonable. Try not to make our site worse, we don't have enough questions (https://chess.meta.stackexchange.com/questions/476/any-possibility-for-chess-to-graduate?cb=1)  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_3 on 2017-05-04. Score: 4
  
  No. You shouldn't count null-move in repetitions because:
  
  Null-move is fake
  Null-move artificially creates a repetition when there is none
  
  Your implementation is correct, but you might want to exclude null-move. Let's take a look at Stockfish:
  
  https://github.com/official-stockfish/Stockfish/blob/master/src/position.cpp
  
  bool Position::is_draw(int ply) const {
  
    if (st->rule50 > 99 && (!checkers() || MoveList(*this).size()))
        return true;
  
    int end = std::min(st->rule50, st->pliesFromNull);
  
    if (end < 4)
      return false;
  
    StateInfo* stp = st->previous->previous;
    int cnt = 0;
  
    for (int i = 4; i <= end; i += 2)
    {
        stp = stp->previous->previous;
  
        // At root position ply is 1, so return a draw score if a position
        // repeats once earlier but after or at the root, or repeats twice
        // strictly before the root.
        if (   stp->key == st->key
            && ++cnt + (ply - i > 0) == 2)
            return true;
    }
  
    return false;
  }
  
  You already have st->rule50 in your code (board->fifty-move) but you don't have st->pliesFromNull.
  Let's check what Stockfish author said about pilesFromNull.
  
  http://www.talkchess.com/forum/viewtopic.php?start=0&t=35052&topic_view=flat&sid=46a5561bcd0c4d36796c0fbfe5158079
  
  By Joona Kiiski (2010):
  They are already excluded, note the use of st->pliesFromNull: 
  
  Null moves can artificially create a repetition 
  draw where instead there is no one. 
  
  So use a second counter to reset history after a null move. 
  
  You see, if the strongest engine in the world does it you have no reason for not doing it.
  If you check the code carefully, the first time when you do a null-move pliesFromNull is 0.
  void Position::do_null_move(StateInfo& newSt) {
      ....
      st->pliesFromNull = 0;
  }
  
  later the engine increments the counter in do_move:
  ++st->pliesFromNull;
  
  
  ---
  
  