3 fold repetition scoring issue

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

3 fold repetition scoring issue

Post by maksimKorzh »

Hi guys

I've just implemented repetition detection in my engine
and the detection itself seems to be working correctly:

Code: Select all

  8  . . ♜ . . . ♚ .
  7  ♖ . . . . . . .
  6  . . . . . . . .
  5  . ♖ . . . . . .
  4  . . . . . . . .
  3  . . . . . . . .
  2  ♙ . . . . ♔ ♙ ♙
  1  . . . . . . . .

     a b c d e f g h

     Side:     white
     Enpassant:   no
     Castling:  ----

     Hash key:  b237bb9812e3bda

info score cp 890 depth 1 nodes 43 time -1328225343 pv b5b7 
info score cp 900 depth 2 nodes 216 time -1328225342 pv b5g5 g8f8 g5g7 
repetition dedected!
repetition dedected!
repetition dedected!
repetition dedected!
info score cp 890 depth 3 nodes 642 time -1328225341 pv b5g5 g8f8 g5f5 f8g8 f5f7
But if I return 0 when repetition is found for some reason I'm getting the same score
and the number of traversed nodes increases and PV is still the same:

Code: Select all


  8  . . ♜ . . . ♚ .
  7  ♖ . . . . . . .
  6  . . . . . . . .
  5  . ♖ . . . . . .
  4  . . . . . . . .
  3  . . . . . . . .
  2  ♙ . . . . ♔ ♙ ♙
  1  . . . . . . . .

     a b c d e f g h

     Side:     white
     Enpassant:   no
     Castling:  ----

     Hash key:  b237bb9812e3bda

info score cp 890 depth 1 nodes 43 time -1328247751 pv b5b7 
info score cp 900 depth 2 nodes 216 time -1328247750 pv b5g5 g8f8 g5g7 
info score cp 890 depth 3 nodes 658 time -1328247748 pv b5g5 g8f8 g5f5 f8g8 f5f7
Now regarding the place where I'm looking for repetitions:

Code: Select all

int negamax(int alpha, int beta, int depth)
{
    if (ply && is_repetition())
        return 0; // printf("repetition detected!\n")
    
    // read hash entry
    if (read_hash_entry(...))
        // return hash score...
}

What am I doing wrong?
Should score get changed to 0 instead of 890?
Should PV change?
mar
Posts: 2554
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: 3 fold repetition scoring issue

Post by mar »

fist of all, you detect a repetition down the tree, so the search may pick another path if it's better
also, you should check for the repetition of a position, not when a single piece repeats a move (because the position may still differ)
Last edited by mar on Mon Sep 21, 2020 5:19 pm, edited 1 time in total.
Martin Sedlak
No4b
Posts: 105
Joined: Thu Jun 18, 2020 3:21 pm
Location: Moscow
Full name: Alexander Litov

Re: 3 fold repetition scoring issue

Post by No4b »

maksimKorzh wrote: Mon Sep 21, 2020 3:47 pm Hi guys

I've just implemented repetition detection in my engine
and the detection itself seems to be working correctly:

Code: Select all

  8  . . ♜ . . . ♚ .
  7  ♖ . . . . . . .
  6  . . . . . . . .
  5  . ♖ . . . . . .
  4  . . . . . . . .
  3  . . . . . . . .
  2  ♙ . . . . ♔ ♙ ♙
  1  . . . . . . . .

     a b c d e f g h

     Side:     white
     Enpassant:   no
     Castling:  ----

     Hash key:  b237bb9812e3bda

info score cp 890 depth 1 nodes 43 time -1328225343 pv b5b7 
info score cp 900 depth 2 nodes 216 time -1328225342 pv b5g5 g8f8 g5g7 
repetition dedected!
repetition dedected!
repetition dedected!
repetition dedected!
info score cp 890 depth 3 nodes 642 time -1328225341 pv b5g5 g8f8 g5f5 f8g8 f5f7
But if I return 0 when repetition is found for some reason I'm getting the same score
and the number of traversed nodes increases and PV is still the same:

Code: Select all


  8  . . ♜ . . . ♚ .
  7  ♖ . . . . . . .
  6  . . . . . . . .
  5  . ♖ . . . . . .
  4  . . . . . . . .
  3  . . . . . . . .
  2  ♙ . . . . ♔ ♙ ♙
  1  . . . . . . . .

     a b c d e f g h

     Side:     white
     Enpassant:   no
     Castling:  ----

     Hash key:  b237bb9812e3bda

info score cp 890 depth 1 nodes 43 time -1328247751 pv b5b7 
info score cp 900 depth 2 nodes 216 time -1328247750 pv b5g5 g8f8 g5g7 
info score cp 890 depth 3 nodes 658 time -1328247748 pv b5g5 g8f8 g5f5 f8g8 f5f7
Now regarding the place where I'm looking for repetitions:

Code: Select all

int negamax(int alpha, int beta, int depth)
{
    if (ply && is_repetition())
        return 0; // printf("repetition detected!\n")
    
    // read hash entry
    if (read_hash_entry(...))
        // return hash score...
}

What am I doing wrong?
Should score get changed to 0 instead of 890?
Should PV change?
Well, if i understand the position correctily white is Rook and 3 pawns up, and black has no way of forcing them to repeat position, so
score should not get changed (because 3-fold branches either be prunned or never be chosen).

You should use different test position if you want you engine to change eval and PV.
You can try finding some puzzles, where 3-fold is forced after some sacrifice by losing side, at least in my case
use of such positions did a great help with debugging
Pio
Posts: 334
Joined: Sat Feb 25, 2012 10:42 pm
Location: Stockholm

Re: 3 fold repetition scoring issue

Post by Pio »

maksimKorzh wrote: Mon Sep 21, 2020 3:47 pm Hi guys

I've just implemented repetition detection in my engine
and the detection itself seems to be working correctly:

Code: Select all

  8  . . ♜ . . . ♚ .
  7  ♖ . . . . . . .
  6  . . . . . . . .
  5  . ♖ . . . . . .
  4  . . . . . . . .
  3  . . . . . . . .
  2  ♙ . . . . ♔ ♙ ♙
  1  . . . . . . . .

     a b c d e f g h

     Side:     white
     Enpassant:   no
     Castling:  ----

     Hash key:  b237bb9812e3bda

info score cp 890 depth 1 nodes 43 time -1328225343 pv b5b7 
info score cp 900 depth 2 nodes 216 time -1328225342 pv b5g5 g8f8 g5g7 
repetition dedected!
repetition dedected!
repetition dedected!
repetition dedected!
info score cp 890 depth 3 nodes 642 time -1328225341 pv b5g5 g8f8 g5f5 f8g8 f5f7
But if I return 0 when repetition is found for some reason I'm getting the same score
and the number of traversed nodes increases and PV is still the same:

Code: Select all


  8  . . ♜ . . . ♚ .
  7  ♖ . . . . . . .
  6  . . . . . . . .
  5  . ♖ . . . . . .
  4  . . . . . . . .
  3  . . . . . . . .
  2  ♙ . . . . ♔ ♙ ♙
  1  . . . . . . . .

     a b c d e f g h

     Side:     white
     Enpassant:   no
     Castling:  ----

     Hash key:  b237bb9812e3bda

info score cp 890 depth 1 nodes 43 time -1328247751 pv b5b7 
info score cp 900 depth 2 nodes 216 time -1328247750 pv b5g5 g8f8 g5g7 
info score cp 890 depth 3 nodes 658 time -1328247748 pv b5g5 g8f8 g5f5 f8g8 f5f7
Now regarding the place where I'm looking for repetitions:

Code: Select all

int negamax(int alpha, int beta, int depth)
{
    if (ply && is_repetition())
        return 0; // printf("repetition detected!\n")
    
    // read hash entry
    if (read_hash_entry(...))
        // return hash score...
}

What am I doing wrong?
Should score get changed to 0 instead of 890?
Should PV change?
I don’t know what your ply is or how your repetition code looks like, but it seems right that you will find some repetitions after four half moves. That you will get the same score seems also be right since the repetition lines will not become the PV and hence not propagate the score.
User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Re: 3 fold repetition scoring issue

Post by maksimKorzh »

Thank you guys!
User avatar
maksimKorzh
Posts: 771
Joined: Sat Sep 08, 2018 5:37 pm
Location: Ukraine
Full name: Maksim Korzh

Re: 3 fold repetition scoring issue

Post by maksimKorzh »

No4b wrote: Mon Sep 21, 2020 5:19 pm
maksimKorzh wrote: Mon Sep 21, 2020 3:47 pm Hi guys

I've just implemented repetition detection in my engine
and the detection itself seems to be working correctly:

Code: Select all

  8  . . ♜ . . . ♚ .
  7  ♖ . . . . . . .
  6  . . . . . . . .
  5  . ♖ . . . . . .
  4  . . . . . . . .
  3  . . . . . . . .
  2  ♙ . . . . ♔ ♙ ♙
  1  . . . . . . . .

     a b c d e f g h

     Side:     white
     Enpassant:   no
     Castling:  ----

     Hash key:  b237bb9812e3bda

info score cp 890 depth 1 nodes 43 time -1328225343 pv b5b7 
info score cp 900 depth 2 nodes 216 time -1328225342 pv b5g5 g8f8 g5g7 
repetition dedected!
repetition dedected!
repetition dedected!
repetition dedected!
info score cp 890 depth 3 nodes 642 time -1328225341 pv b5g5 g8f8 g5f5 f8g8 f5f7
But if I return 0 when repetition is found for some reason I'm getting the same score
and the number of traversed nodes increases and PV is still the same:

Code: Select all


  8  . . ♜ . . . ♚ .
  7  ♖ . . . . . . .
  6  . . . . . . . .
  5  . ♖ . . . . . .
  4  . . . . . . . .
  3  . . . . . . . .
  2  ♙ . . . . ♔ ♙ ♙
  1  . . . . . . . .

     a b c d e f g h

     Side:     white
     Enpassant:   no
     Castling:  ----

     Hash key:  b237bb9812e3bda

info score cp 890 depth 1 nodes 43 time -1328247751 pv b5b7 
info score cp 900 depth 2 nodes 216 time -1328247750 pv b5g5 g8f8 g5g7 
info score cp 890 depth 3 nodes 658 time -1328247748 pv b5g5 g8f8 g5f5 f8g8 f5f7
Now regarding the place where I'm looking for repetitions:

Code: Select all

int negamax(int alpha, int beta, int depth)
{
    if (ply && is_repetition())
        return 0; // printf("repetition detected!\n")
    
    // read hash entry
    if (read_hash_entry(...))
        // return hash score...
}

What am I doing wrong?
Should score get changed to 0 instead of 890?
Should PV change?
Well, if i understand the position correctily white is Rook and 3 pawns up, and black has no way of forcing them to repeat position, so
score should not get changed (because 3-fold branches either be prunned or never be chosen).

You should use different test position if you want you engine to change eval and PV.
You can try finding some puzzles, where 3-fold is forced after some sacrifice by losing side, at least in my case
use of such positions did a great help with debugging
Could you please give me a link to 3 fold repetition positions?
brianr
Posts: 536
Joined: Thu Mar 09, 2006 3:01 pm

Re: 3 fold repetition scoring issue

Post by brianr »

3 rep scoring can be quite tricky.

Many A/B engines look for 3 reps at the root and score only 2 reps in the search tree as a draw.

FWIW:
I tend to think of 3 reps (and rule 50 moves) as more of a search issue, and not something in the eval (which typically has no knowledge of the prior positions). This is like the in-check search depth extension, so I don't score being in check in the eval either.

Most eval calls are in q-search, and there typically only quiet positions (no good captures per SEE, no promotion, etc) are the ones evaluated. The exceptions are at the extreme maximum depth limit (which can happen in late endgames, although less often with tablebases), and during eval window type pruning in the search.

I went around and around with 3 reps using various test positions. Some would work and then others would not.
In the end, suggest using whatever gains you the most Elo against a mix of comparable opponents (not just self-play).

Of course, how you then handle draws is another area entirely.

PS: As usual, the Crafty source code has lots of well-commented (well-commented to me) code to study for ideas.
chrisw
Posts: 4313
Joined: Tue Apr 03, 2012 4:28 pm

Re: 3 fold repetition scoring issue

Post by chrisw »

brianr wrote: Mon Sep 21, 2020 8:10 pm 3 rep scoring can be quite tricky.

Many A/B engines look for 3 reps at the root and score only 2 reps in the search tree as a draw.

FWIW:
I tend to think of 3 reps (and rule 50 moves) as more of a search issue, and not something in the eval (which typically has no knowledge of the prior positions). This is like the in-check search depth extension, so I don't score being in check in the eval either.

Most eval calls are in q-search, and there typically only quiet positions (no good captures per SEE, no promotion, etc) are the ones evaluated. The exceptions are at the extreme maximum depth limit (which can happen in late endgames, although less often with tablebases), and during eval window type pruning in the search.

I went around and around with 3 reps using various test positions. Some would work and then others would not.
In the end, suggest using whatever gains you the most Elo against a mix of comparable opponents (not just self-play).

Of course, how you then handle draws is another area entirely.

PS: As usual, the Crafty source code has lots of well-commented (well-commented to me) code to study for ideas.
Some time back, when I was going to town on PERFT EPDs trying to find (and make) ones that tested everything, I always intended to make some EPDs that stress tested draw code in search (draws are terminal so they remove PERFT nodes obviously), but never got round to it.
No4b
Posts: 105
Joined: Thu Jun 18, 2020 3:21 pm
Location: Moscow
Full name: Alexander Litov

Re: 3 fold repetition scoring issue

Post by No4b »

Its pretty easy to come up with those positions, if you check result with some strong engine (SF):

fe
k7/p2p1ppp/P5qn/3p4/Q2p2P1/1N5P/5P2/5RK1 b - - 0 1

Blacks best and only move is Ng4 with score 0.00
JVMerlino
Posts: 1357
Joined: Wed Mar 08, 2006 10:15 pm
Location: San Francisco, California

Re: 3 fold repetition scoring issue

Post by JVMerlino »

This is probably the easiest position I have. Your engine should avoid Qxa6 and Rxa6 as they both lead to an immediate 3-fold draw:
[d]3r3N/R1p1kppp/n6n/8/2QPP3/5q2/5P1P/5RK1 w - - 0 24

Also, this is a classic position, but it is much harder for young engines to find:
[d]1k6/4R3/1p6/p1p3p1/qnBn2Qp/5P2/1P6/1K6 w - - 0 46
Bb3! eventually leads to draw either by repetition or stalemate