user12906: I'm making a chess engine that has to implement a three-fold repetition as my AI vs AI engine repeats the same moves over and over again (Have a look at my post here - My chess AI makes the same repeated moves). I've read the rules of this scenario from the wiki and would like to implement it. I'm not sure if I have understood the rules thoroughly, so what I'm doing here is - 

Checking if the present move made (from the movelog I have) has already occurred before.
If it did, check for one more occurrence (as we need three in total).
If the moves pattern for all the three re-occurred moves is same, return true.

Please have a look at my Java code and suggest me the corrections.
    boolean isThreeFoldRepetition() {
        List<Move> allMoves = Table.get().getMoveLog().getMoves();
        int currentMoveIndex = allMoves.size()-1;
        int secondFoldMoveIndex = currentMoveIndex - 4;
        int firstFoldMoveIndex = secondFoldMoveIndex - 4;
        int distance = currentMoveIndex - secondFoldMoveIndex - 1;

        while(firstFoldMoveIndex >= 0){
            Move thirdFoldMoveMade = allMoves.get(currentMoveIndex);
            Move secondFoldMoveMade = allMoves.get(secondFoldMoveIndex);
            Move firstFoldMoveMade = allMoves.get(firstFoldMoveIndex);

            if(thirdFoldMoveMade.equals(secondFoldMoveMade) &&
               secondFoldMoveMade.equals(firstFoldMoveMade) &&
               firstFoldMoveIndex - distance >= 0){
                int gap;
                for(gap = 1; gap <= distance; gap++){
                    thirdFoldMoveMade = allMoves.get(currentMoveIndex - gap);
                    secondFoldMoveMade = allMoves.get(secondFoldMoveIndex - gap);
                    firstFoldMoveMade = allMoves.get(firstFoldMoveIndex - gap);

                    if(!thirdFoldMoveMade.equals(secondFoldMoveMade) || !secondFoldMoveMade.equals(firstFoldMoveMade))
                        break;
                }
                if(gap == distance)
                    return true;
            }

            secondFoldMoveIndex -= 2;
            firstFoldMoveIndex = secondFoldMoveIndex - distance - 3;
        }
        return false;
    }


user12273: I would look at the source code for TSCP which implements zobrist keys. Basically you assign a unique number to each position and store the numbers in a list. Then check if the same number is in the list three times. you generate the unique number based on the position of the pieces, en passant square, side to move. here i have copied and pasted the TSCP code (authored by Tom Kerrigan). hash_piece is indexed by the color(2), piece type(6), and position(64). hash_side is the side to move. hash_ep is the en passant square. The initialization function populates a table of random numbers for each of these possible entries. To generate the unique position for a position
you look up all the entries correspoding to a given position and xor the numbers from the three tables (this is the set_hash function). You probably dont need the hash_rand on newer computers with better random number generators. 
void init_hash()
    {
        int i, j, k;

        srand(0);
        for (i = 0; i < 2; ++i)
            for (j = 0; j < 6; ++j)
                for (k = 0; k < 64; ++k)
                    hash_piece[i][j][k] = hash_rand();
        hash_side = hash_rand();
        for (i = 0; i < 64; ++i)
            hash_ep[i] = hash_rand();
    }


    /* hash_rand() XORs some shifted random numbers together to make sure
       we have good coverage of all 32 bits. (rand() returns 16-bit numbers
       on some systems.) */

    int hash_rand()
    {
        int i;
        int r = 0;

        for (i = 0; i < 32; ++i)
            r ^= rand() << i;
        return r;
    }


    /* set_hash() uses the Zobrist method of generating a unique number (hash)
       for the current chess position. Of course, there are many more chess
       positions than there are 32 bit numbers, so the numbers generated are
       not really unique, but they're unique enough for our purposes (to detect
       repetitions of the position). 
       The way it works is to XOR random numbers that correspond to features of
       the position, e.g., if there's a black knight on B8, hash is XORed with
       hash_piece[BLACK][KNIGHT][B8]. All of the pieces are XORed together,
       hash_side is XORed if it's black's move, and the en passant square is
       XORed if there is one. (A chess technicality is that one position can't
       be a repetition of another if the en passant state is different.) */

    void set_hash()
    {
        int i;

        hash = 0;   
        for (i = 0; i < 64; ++i)
            if (color[i] != EMPTY)
                hash ^= hash_piece[color[i]][piece[i]][i];
        if (side == DARK)
            hash ^= hash_side;
        if (ep != -1)
            hash ^= hash_ep[ep];
    }


user825: Although @user1583209 is on the right track. His approach would only work for a chess GUI but too slow for a chess engine. Modern engines only check for the last few moves, they won't go all the way back to the initial position because that'd be an almost waste of time.
You have complicated your code too much. In reality, checking for repetition is very simple:

https://github.com/official-stockfish/Stockfish/blob/master/src/position.cpp

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;
}

You go back in the history and check the key for your position. Very simple. You may want to ignore the ply check.
You should have a way to hash your position, if you don't you will need it for transposition table anyway. 
A useful reference link to prove my idea is correct:

http://talkchess.com/forum/viewtopic.php?t=59322&highlight=move+repetitions


user11629: Threefold-repetition is about a position (not moves) occurring three times. Those positions do not have to be reached by the same moves. 
Also (as this also seems to be confused sometimes) it is completely irrelevant when this happens, e.g. you can have the same positions after moves 10, 42 and 63 and it would still be a draw. 
You should check whether the position is repeated. So basically at every move you need to check whether the position occurred in the game before. By position I mean the same position of all pieces on the board and the same castling rights and the same player to move and the same enpassant rights. That is, basically you are checking whether the FEN are the same (except for halfmove clock and fullmove number).
Something like:
int positionCount=0;
while(iterate through game positions) {
    if ( positionToCheck.piecesPosition == iterationPosition.piecesPosition && 
         positionToCheck.castleRights == iterationPosition.castleRights && 
         positionToCheck.enPassantRights == iterationPosition.enPassantRights &&
         positionToCheck.playerToMove == iterationPosition.playerToMove ) {
      positionCount++;
    }
    if (positionCount==3) { return true; }
}
return false;

Of course you can simplify the above algorithm. E.g. you only need to iterate over position with the same player to move. Also you only need to iterate over positions back to the last pawn move, capture or castling move.

12906: <p>I'm making a chess engine that has to implement a three-fold repetition as my AI vs AI engine repeats the same moves over and over again (Have a look at my post here - <a href="https://chess.stackexchange.com/questions/17075/my-chess-ai-makes-the-same-repeated-moves">My chess AI makes the same repeated moves</a>). I've read the rules of this scenario from the wiki and would like to implement it. I'm not sure if I have understood the rules thoroughly, so what I'm doing here is - </p>

<ol>
<li>Checking if the present move made (from the movelog I have) has already occurred before.</li>
<li>If it did, check for one more occurrence (as we need three in total).</li>
<li>If the moves pattern for all the three re-occurred moves is same, return true.</li>
</ol>

<p>Please have a look at my Java code and suggest me the corrections.</p>

<pre><code>    boolean isThreeFoldRepetition() {
        List&lt;Move&gt; allMoves = Table.get().getMoveLog().getMoves();
        int currentMoveIndex = allMoves.size()-1;
        int secondFoldMoveIndex = currentMoveIndex - 4;
        int firstFoldMoveIndex = secondFoldMoveIndex - 4;
        int distance = currentMoveIndex - secondFoldMoveIndex - 1;

        while(firstFoldMoveIndex &gt;= 0){
            Move thirdFoldMoveMade = allMoves.get(currentMoveIndex);
            Move secondFoldMoveMade = allMoves.get(secondFoldMoveIndex);
            Move firstFoldMoveMade = allMoves.get(firstFoldMoveIndex);

            if(thirdFoldMoveMade.equals(secondFoldMoveMade) &amp;&amp;
               secondFoldMoveMade.equals(firstFoldMoveMade) &amp;&amp;
               firstFoldMoveIndex - distance &gt;= 0){
                int gap;
                for(gap = 1; gap &lt;= distance; gap++){
                    thirdFoldMoveMade = allMoves.get(currentMoveIndex - gap);
                    secondFoldMoveMade = allMoves.get(secondFoldMoveIndex - gap);
                    firstFoldMoveMade = allMoves.get(firstFoldMoveIndex - gap);

                    if(!thirdFoldMoveMade.equals(secondFoldMoveMade) || !secondFoldMoveMade.equals(firstFoldMoveMade))
                        break;
                }
                if(gap == distance)
                    return true;
            }

            secondFoldMoveIndex -= 2;
            firstFoldMoveIndex = secondFoldMoveIndex - distance - 3;
        }
        return false;
    }
</code></pre>
 12273: <p>I would look at the source code for TSCP which implements zobrist keys. Basically you assign a unique number to each position and store the numbers in a list. Then check if the same number is in the list three times. you generate the unique number based on the position of the pieces, en passant square, side to move. here i have copied and pasted the TSCP code (authored by Tom Kerrigan). hash_piece is indexed by the color(2), piece type(6), and position(64). hash_side is the side to move. hash_ep is the en passant square. The initialization function populates a table of random numbers for each of these possible entries. To generate the unique position for a position<br>
you look up all the entries correspoding to a given position and xor the numbers from the three tables (this is the set_hash function). You probably dont need the hash_rand on newer computers with better random number generators. </p>

<pre><code>void init_hash()
    {
        int i, j, k;

        srand(0);
        for (i = 0; i &lt; 2; ++i)
            for (j = 0; j &lt; 6; ++j)
                for (k = 0; k &lt; 64; ++k)
                    hash_piece[i][j][k] = hash_rand();
        hash_side = hash_rand();
        for (i = 0; i &lt; 64; ++i)
            hash_ep[i] = hash_rand();
    }


    /* hash_rand() XORs some shifted random numbers together to make sure
       we have good coverage of all 32 bits. (rand() returns 16-bit numbers
       on some systems.) */

    int hash_rand()
    {
        int i;
        int r = 0;

        for (i = 0; i &lt; 32; ++i)
            r ^= rand() &lt;&lt; i;
        return r;
    }


    /* set_hash() uses the Zobrist method of generating a unique number (hash)
       for the current chess position. Of course, there are many more chess
       positions than there are 32 bit numbers, so the numbers generated are
       not really unique, but they're unique enough for our purposes (to detect
       repetitions of the position). 
       The way it works is to XOR random numbers that correspond to features of
       the position, e.g., if there's a black knight on B8, hash is XORed with
       hash_piece[BLACK][KNIGHT][B8]. All of the pieces are XORed together,
       hash_side is XORed if it's black's move, and the en passant square is
       XORed if there is one. (A chess technicality is that one position can't
       be a repetition of another if the en passant state is different.) */

    void set_hash()
    {
        int i;

        hash = 0;   
        for (i = 0; i &lt; 64; ++i)
            if (color[i] != EMPTY)
                hash ^= hash_piece[color[i]][piece[i]][i];
        if (side == DARK)
            hash ^= hash_side;
        if (ep != -1)
            hash ^= hash_ep[ep];
    }
</code></pre>
 825: <p>Although @user1583209 is on the right track. His approach would only work for a chess GUI but too <strong>slow</strong> for a chess engine. Modern engines only check for the last few moves, they won't go all the way back to the initial position because that'd be an almost waste of time.</p>

<p>You have complicated your code too much. In reality, checking for repetition is very simple:</p>

<blockquote>
  <p><a href="https://github.com/official-stockfish/Stockfish/blob/master/src/position.cpp" rel="noreferrer">https://github.com/official-stockfish/Stockfish/blob/master/src/position.cpp</a></p>
</blockquote>

<pre><code>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;
}
</code></pre>

<p>You go back in the history and check the key for your position. <strong>Very simple</strong>. You may want to ignore the <code>ply</code> check.</p>

<p>You should have a way to hash your position, if you don't you will need it for transposition table anyway. </p>

<p>A useful reference link to prove my idea is correct:</p>

<blockquote>
  <p><a href="http://talkchess.com/forum/viewtopic.php?t=59322&amp;highlight=move+repetitions" rel="noreferrer">http://talkchess.com/forum/viewtopic.php?t=59322&amp;highlight=move+repetitions</a></p>
</blockquote>
 11629: <p>Threefold-repetition is about <strong>a position</strong> (not moves) occurring three times. Those positions <strong>do not</strong> have to be reached by the same moves. </p>

<p>Also (as this also seems to be confused sometimes) it is completely irrelevant when this happens, e.g. you can have the same positions after moves 10, 42 and 63 and it would still be a draw. </p>

<p>You should check whether the position is repeated. So basically at every move you need to check whether the position occurred in the game before. By <em>position</em> I mean the same position of all pieces on the board <em>and</em> the same castling rights <em>and</em> the same player to move <em>and</em> the same enpassant rights. That is, basically you are checking whether the <a href="https://en.wikipedia.org/wiki/Forsyth%E2%80%93Edwards_Notation" rel="nofollow noreferrer">FEN</a> are the same (except for halfmove clock and fullmove number).</p>

<p>Something like:</p>

<pre><code>int positionCount=0;
while(iterate through game positions) {
    if ( positionToCheck.piecesPosition == iterationPosition.piecesPosition &amp;&amp; 
         positionToCheck.castleRights == iterationPosition.castleRights &amp;&amp; 
         positionToCheck.enPassantRights == iterationPosition.enPassantRights &amp;&amp;
         positionToCheck.playerToMove == iterationPosition.playerToMove ) {
      positionCount++;
    }
    if (positionCount==3) { return true; }
}
return false;
</code></pre>

<p>Of course you can simplify the above algorithm. E.g. you only need to iterate over position with the same player to move. Also you only need to iterate over positions back to the last pawn move, capture or castling move.</p>
