Added repetition detection but in some games repeats

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

tttony
Posts: 268
Joined: Sun Apr 24, 2011 12:33 am

Added repetition detection but in some games repeats

Post by tttony »

I recently added repetition detection and it works partially fine, now it's winning more games than before but in some games ends in repetition even with a win position, like this one:

[pgn]
[Event "Skiull_0.1_vs_Skiull_0.2_1m1s_REP"]
[Site "HIGH-PC"]
[Date "2017.04.25"]
[Round "981"]
[White "Skiull 0.2 x64"]
[Black "Skiull 0.1 x64"]
[Result "1/2-1/2"]
[BlackElo "1500"]
[ECO "D15"]
[Opening "Slav"]
[Time "04:26:14"]
[Variation "Chameleon, 5.a4 e6 6.Bg5"]
[WhiteElo "1500"]
[TimeControl "60+1"]
[Termination "normal"]
[PlyCount "157"]
[WhiteType "human"]
[BlackType "human"]

1. Nf3 c5 2. d4 e6 3. e3 {(e2-e3 Ng8-f6 Bf1-b5 a7-a6 Bb5-d3 d7-d5 Nb1-c3
Nb8-c6 O-O) +0.55/9 2} cxd4 {(c5xd4) -0.30/7 2} 4. exd4 {(e3xd4 Nb8-c6
Nb1-c3 d7-d5 Bf1-b5 Ng8-e7 O-O Bc8-d7) +0.45/9 2} Nc6 {(Nb8-c6) -0.60/6 2}
5. Bb5 {(Bf1-b5 Ng8-e7 Nb1-c3 d7-d5 Bb5xc6+ Ne7xc6 O-O Bf8-b4 Bc1-g5)
+0.55/9 2} Nf6 {(Ng8-f6) -0.45/7 2} 6. O-O {(O-O d7-d5 Bb5xc6+ b7xc6 Nb1-c3
Bf8-d6 Bc1-e3 O-O Nf3-e5) +0.55/9 2} d5 {(d7-d5) -0.50/7 2} 7. Bxc6+
{(Bb5xc6+ b7xc6 Nb1-c3 Bf8-b4 Bc1-g5 O-O Bg5xf6 Qd8xf6 Nc3-e2) +0.50/9 2}
bxc6 {(b7xc6) -0.50/7 2} 8. Nc3 {(Nb1-c3 Bf8-b4 Bc1-d2 O-O a2-a3 Bb4xc3
Bd2xc3 Bc8-b7) +0.35/8 2} Bb4 {(Bf8-b4) -0.50/6 2} 9. Ne5 {(Nf3-e5 Bb4xc3
b2xc3 O-O Bc1-g5 Bc8-b7) +0.40/10 2} Bxc3 {(Bb4xc3) -0.35/7 2} 10. bxc3
{(b2xc3) +0.40/9 2} O-O {-0.40/6 2 (O-O)} 11. Bg5 {(Bc1-g5 Qd8-d6 c3-c4
Nf6-e4 Bg5-f4 Qd6-a3 Ne5xc6 d5xc4 Nc6-e5) +0.40/9 2} Qd6 {(Qd8-d6) -0.40/7
2} 12. c4 {(c3-c4 Nf6-e4 c4-c5 Qd6-c7 Bg5-f4 Rf8-d8 Ne5-d3 Qc7-a5) +0.40/8
2} c5 {(c6-c5) -0.40/7 2} 13. Bxf6 {(Bg5xf6 g7xf6 Ne5-d3 d5xc4 Qd1-g4+
Kg8-h8 Nd3xc5 e6-e5 Qg4-f3 Bc8-e6) +0.30/10 2} gxf6 {(g7xf6) -0.50/7 2} 14.
Nd3 {(Ne5-d3 d5xc4 Qd1-g4+ Kg8-h8 Nd3xc5 e6-e5 Qg4-e4 Bc8-e6 Ra1-d1 c4-c3)
+0.30/10 2} dxc4 {(d5xc4) -0.40/8 2} 15. Qg4+ {(Qd1-g4+ Kg8-h8 Nd3xc5 e6-e5
Qg4-e4 Ra8-b8 Ra1-d1 Rb8-b2 Qe4-e2) +0.20/9 2} Kh8 {(Kg8-h8) -0.20/8 2} 16.
Nxc5 {(Nd3xc5 e6-e5 Qg4-f3 Ra8-b8 Nc5-e4 Qd6xd4 Qf3xf6+ Kh8-g8 Qf6-g5+
Kg8-h8) +0.25/10 2} e5 {(e6-e5) -0.20/7 2} 17. Qf3 {(Qg4-f3 Ra8-b8 Nc5-e4
Qd6-d8 d4xe5 f6xe5 Ra1-d1 Qd8-h4 Qf3-f6+ Qh4xf6) +0.25/10 2} Rb8 {(Ra8-b8)
-0.25/7 2} 18. Ne4 {(Nc5-e4 Qd6-d8 d4-d5 f6-f5 Qf3-h5 Rf8-g8 Rf1-d1 Rb8-b2
Ne4-c5) +0.30/9 2} Qd8 {(Qd6-d8) -0.25/7 2} 19. dxe5 {(d4xe5 f6xe5 Rf1-d1
Qd8-a5 Qf3-h5 f7-f5 Ne4-g5 Rb8-b7 Ng5-f3) +0.30/10 2} fxe5 {(f6xe5) -0.15/7
2} 20. Rad1 {(Ra1-d1 Qd8-e7 Qf3-c3 Rb8-b4 f2-f4 Bc8-g4 Rd1-d6 Rb4-a4)
+0.30/8 1} Qe7 {(Qd8-e7) -0.20/6 1} 21. Qc3 {(Qf3-c3 Bc8-a6 f2-f4 f7-f6
f4-f5 Ba6-b5 Qc3-e3 a7-a6) +0.45/9 1} Ba6 {(Bc8-a6) -0.55/6 1} 22. f4
{(f2-f4 f7-f6 f4-f5 Qe7-b7 Rf1-e1 Ba6-b5 a2-a4 Bb5-d7) +0.45/9 1} f6
{(f7-f6) -0.45/7 1} 23. fxe5 {(f4xe5 f6xe5 Rf1xf8+ Rb8xf8 Qc3-a5 Ba6-b7
Qa5xa7 Rf8-e8 Rd1-e1) +1.15/10 1} fxe5 {(f6xe5) -1.15/7 1} 24. Rxf8+
{(Rf1xf8+ Rb8xf8 Rd1-d5 Rf8-f5 Rd5-a5 Ba6-b7 Ra5xa7 Qe7-h4 Ne4-c5) +1.30/10
1} Rxf8 {(Rb8xf8) -1.30/8 1} 25. Rd5 {(Rd1-d5 Rf8-f5 Qc3-a5 Qe7-f8 Ne4-g3
Ba6-b7 Rd5-d7 Bb7-c6 Rd7xa7) +1.15/10 1} Rf5 {(Rf8-f5) -0.80/7 1} 26. Qa5
{(Qc3-a5 Ba6-b7 Qa5-d8+ Qe7-f8 Qd8xf8+ Rf5xf8 Rd5xe5 Kh8-g8 Ne4-c5)
+1.25/10 1} Bb7 {(Ba6-b7) -1.20/7 1} 27. Qd8+ {(Qa5-d8+ Qe7-f8 Qd8xf8+
Rf5xf8 Rd5xe5 Rf8-d8 Ne4-c5 Bb7-d5 Re5-e7 Rd8-c8 Nc5-d7) +1.60/11 1} Qf8
{(Qe7-f8) -1.60/8 1} 28. Qxf8+ {(Qd8xf8+ Rf5xf8 Rd5xe5 Rf8-d8 Re5-e7 Bb7xe4
Re7xe4) +1.55/12 1} Rxf8 {(Rf5xf8) -1.60/8 1} 29. Rxe5 {(Rd5xe5 Rf8-d8
Re5-e7 Bb7xe4) +1.55/10 1} Rd8 {(Rf8-d8) -1.60/6 1} 30. Re7 {(Re5-e7 Bb7xe4
Re7xe4 c4-c3 Re4-e3 Rd8-d1+ Kg1-f2 Rd1-d2+ Re3-e2) +1.45/9 1} Bxe4
{(Bb7xe4) -1.45/8 1} 31. Rxe4 {(Re7xe4 Rd8-d1+ Kg1-f2 Rd1-d2+ Re4-e2 Rd2-d7
Kf2-e3 Kh8-g7 Re2-f2 c4-c3 Ke3-e4 Rd7-d2 Rf2-e2) +1.25/14 1} c3 {(c4-c3)
-1.10/8 1} 32. Re3 {(Re4-e3 Rd8-d1+ Kg1-f2 Rd1-d2+ Re3-e2 Rd2-d4 Kf2-f3
Rd4-a4 Re2-e8+ Kh8-g7 Re8-e7+ Kg7-f6) +1.25/12 1} Rd1+ {(Rd8-d1+) -1.10/8
1} 33. Kf2 {(Kg1-f2 Rd1-d2+ Re3-e2 Rd2-d4 Kf2-f3 Rd4-a4 Re2-e3 Ra4xa2
Re3xc3 Kh8-g7 Rc3-c7+ Kg7-g6) +1.25/13 1} Rd2+ {(Rd1-d2+) -1.45/8 1} 34.
Re2 {(Re3-e2 Rd2-d6 Kf2-f3 Kh8-g8 Re2-e3 Rd6-f6+ Kf3-e4 Rf6-e6+ Ke4-d3
Re6xe3+ Kd3xe3) +1.30/12 1} Rd4 {(Rd2-d4) -1.30/7 1} 35. Kf3 {(Kf2-f3
Rd4-a4 Re2-e3 Ra4-a3 Kf3-e4 Kh8-g7 Re3-d3 Kg7-f6 Rd3-d6+ Kf6-e7 Rd6-d3)
+1.25/11 1} Ra4 {(Rd4-a4) -1.35/8 1} 36. Re3 {(Re2-e3 Ra4-a3 Kf3-e4 Ra3xa2
Re3xc3 Kh8-g7 h2-h4 h7-h5 Rc3-g3+ Kg7-f6 Rg3-c3 a7-a6 Rc3-c7) +1.35/13 1}
Ra3 {(Ra4-a3) -1.25/9 1} 37. Ke4 {(Kf3-e4 Kh8-g7 Ke4-d4 Ra3xa2 Re3xc3 a7-a6
h2-h3 h7-h6 Rc3-c4 Kg7-f6 Rc4-c7 Ra2-b2) +1.35/12 1} Kg7 {(Kh8-g7) -1.35/8
1} 38. Kd4 {(Ke4-d4 Ra3-a4+ Kd4xc3 Ra4xa2 Re3-e6 Kg7-f7 Re6-c6 h7-h5
Rc6-c7+ Kf7-e6 Kc3-d4 h5-h4) +1.35/13 1} Rxa2 {(Ra3xa2) -1.35/9 1} 39. Rxc3
{(Re3xc3 Kg7-f6 Rc3-c7 h7-h5 Kd4-d5 h5-h4 h2-h3 a7-a6 Kd5-d4 Ra2-b2 Kd4-e4)
+1.35/12 1} a6 {(a7-a6) -1.35/7 1} 40. Rc7+ {(Rc3-c7+ Kg7-f6 Kd4-e4 h7-h6
Ke4-d5 Ra2-b2 h2-h3 a6-a5 Rc7-c6+ Kf6-f5 Rc6-c7 a5-a4) +1.35/13 1} Kf6
{(Kg7-f6) -1.35/9 1} 41. Ke4 {(Kd4-e4 h7-h5 Rc7-c5 Ra2-a4+ Ke4-d5 Ra4-g4
Rc5-c6+ Kf6-f5 g2-g3 h5-h4 g3xh4 Rg4xh4 h2-h3) +1.30/13 1} Ra4+ {(Ra2-a4+)
-1.35/8 1} 42. Kd5 {(Ke4-d5 h7-h5 h2-h3 Ra4-a1 Rc7-c3 Ra1-g1 Rc3-f3+ Kf6-g5
Rf3-g3+ Kg5-f6 Rg3-g8 Rg1-d1+ Kd5-e4) +1.30/13 1} Ra2 {(Ra4-a2) -1.35/8 1}
43. h3 {(h2-h3 Kf6-f5 Kd5-d4 h7-h6 Rc7-c4) +1.30/13 1} h5 {(h7-h5) -1.35/8
1} 44. Rc6+ {(Rc7-c6+ Kf6-f5 Rc6-c7 Ra2-a5+ Kd5-d4 Ra5-a4+ Kd4-d3) +1.30/13
1} Kf5 {(Kf6-f5) -1.35/9 1} 45. Rc3 {(Rc6-c3 Ra2-a5+ Kd5-d4 Ra5-a2 Rc3-f3+
Kf5-e6 Rf3-f2 h5-h4 Rf2-d2 Ra2-b2 Rd2-e2+ Ke6-f5) +1.20/13 1} h4 {(h5-h4)
-1.35/8 1} 46. Rf3+ {(Rc3-f3+ Kf5-g6 Rf3-f2 Ra2-a5+ Kd5-c4 Ra5-a1 Rf2-d2
Kg6-f5 Rd2-d4 Ra1-c1 Kc4-d3 Rc1-d1+ Kd3-c3 Rd1-g1) +1.25/15 1} Kg5
{(Kf5-g5) -1.25/9 1} 47. Rf2 {(Rf3-f2 Ra2-a5+ Kd5-d4 Ra5-a1 c2-c4 Ra1-d1+
Kd4-e4 Rd1-c1 Ke4-d3 Rc1-a1 c4-c5 Ra1-h1 c5-c6 Rh1-c1) +1.25/16 1} Ra1
{(Ra2-a1) -1.25/9 1} 48. Rd2 {(Rf2-d2 Ra1-b1 c2-c4 Rb1-f1 Rd2-e2 Rf1-d1+)
+1.25/13 1} Rb1 {(Ra1-b1) -1.30/8 1} 49. c4 {(c2-c4 Rb1-b8 Rd2-a2 Rb8-d8+
Kd5-e4 Rd8-e8+ Ke4-d3 Re8-e6 Kd3-d4) +1.30/13 1} Rb8 {(Rb1-b8) -1.30/8 1}
50. Ra2 {(Rd2-a2 Rb8-d8+ Kd5-e4 Rd8-e8+ Ke4-d3 Re8-e6 Ra2-f2 Re6-e1 Rf2-f7
Re1-a1 Rf7-g7+ Kg5-f6 Rg7-a7) +1.30/13 1} Rd8+ {(Rb8-d8+) -1.20/9 1} 51.
Ke4 {(Kd5-e4 Rd8-e8+ Ke4-d3 Re8-e6 Ra2-f2 Re6-c6 Kd3-d4 Rc6-d6+ Kd4-e4
Rd6-f6 Rf2xf6 Kg5xf6 c4-c5) +1.35/14 1} Re8+ {(Rd8-e8+) -1.25/9 1} 52. Kd4
{(Ke4-d4 Re8-d8+ Kd4-c3 Rd8-a8 c4-c5 Kg5-f5 c5-c6 Kf5-e6 Ra2-a4 Ke6-d6
Ra4xh4 Kd6xc6 Rh4-h7) +1.35/14 1} Rd8+ {(Re8-d8+) -1.25/9 1} 53. Ke4
{(Kd4-e4 Rd8-e8+) +1.35/14 1} Re8+ {(Rd8-e8+) -1.25/9 1} 54. Kd4 {(Ke4-d4
Re8-d8+ Kd4-c3 Rd8-a8 c4-c5 Kg5-f5 Kc3-c4 Ra8-a7) +1.35/14 1} Rd8+
{(Re8-d8+) -1.25/9 1} 55. Kc3 {(Kd4-c3 Rd8-a8 c4-c5 Kg5-f5 Kc3-d4 Ra8-d8+
Kd4-c4 Rd8-d1 c5-c6 Rd1-c1+ Kc4-d5 Rc1-d1+) +1.40/13 1} Rd6 {(Rd8-d6)
-1.35/9 1} 56. c5 {(c4-c5 Rd6-e6) +1.40/13 1} Re6 {(Rd6-e6) -1.45/8 1} 57.
Rd2 {(Ra2-d2) +1.40/12 1} Kf5 {(Kg5-f5) -1.30/7 1} 58. Rf2+ {(Rd2-f2+
Kf5-e5 Rf2-e2+ Ke5-f5 Re2xe6 Kf5xe6 Kc3-d4 Ke6-f5 c5-c6 Kf5-e6 Kd4-c5)
+1.35/14 1} Ke4 {(Kf5-e4) -1.45/8 1} 59. Kc4 {(Kc3-c4 Ke4-e3 Rf2-f3+ Ke3-e4
Rf3-f8 Ke4-e3 Rf8-g8 Re6-e4+ Kc4-d5 Re4-d4+ Kd5-e5 Rd4-e4+ Ke5-d5) +1.25/14
1} Ke3 {(Ke4-e3) -1.20/8 1} 60. Kd5 {(Kc4-d5 Re6-g6 Rf2-f3+ Ke3-e2 c5-c6
Rg6-g5+ Kd5-d4 Rg5xg2 Rf3-a3) +1.25/14 1} Rg6 {(Re6-g6) -1.15/9 1} 61. Rf3+
{(Rf2-f3+ Ke3-d2 Rf3-a3 Rg6-g5+ Kd5-d4 Rg5-g6 Ra3-a2+ Kd2-e1 Kd4-d5 Rg6-g5+
Kd5-e4 Ke1-f1 c5-c6) +1.35/14 1} Kd2 {(Ke3-d2) -1.35/10 1} 62. c6 {(c5-c6)
+1.55/13 1} Rg5+ {(Rg6-g5+) -1.25/9 1} 63. Kd6 {(Kd5-d6 Rg5-g6+ Kd6-c5
Rg6-g5+ Kc5-b6 Rg5-g6 Rf3-a3 Kd2-c2 Ra3-a4 Kc2-c3 Ra4xh4 Rg6xg2) +1.80/13
1} Rg6+ {(Rg5-g6+) -1.25/9 1} 64. Kc5 {(Kd6-c5 Rg6-g5+ Kc5-b6 Rg5-g6 Rf3-a3
Kd2-c2 Ra3-a4 Kc2-c3 Ra4-g4 Rg6xg4 h3xg4 Kc3-d4) +1.85/13 1} Rg5+
{(Rg6-g5+) -1.70/9 1} 65. Kb6 {(Kc5-b6 Rg5-g6 Rf3-f4 Kd2-c3 Rf4xh4 Rg6xg2)
+1.95/12 1} Rb5+ {(Rg5-b5+) -2.50/8 1} 66. Kxa6 {(Kb6xa6 Rb5-b4 c6-c7
Rb4-c4 Rf3-f7 Kd2-c3 Rf7-d7 Rc4-a4+ Ka6-b5 Ra4-b4+ Kb5-c5 Rb4-c4+ Kc5-d6)
+2.80/13 1} Rc5 {(Rb5-c5) -2.70/9 1} 67. Kb6 {(Ka6-b6 Rc5-e5 c6-c7 Re5-e8
Rf3-f7 Re8-g8 Kb6-b7 Kd2-e3 c7-c8Q Rg8xc8 Kb7xc8 Ke3-e4) +6.05/14 1} Rc4
{(Rc5-c4) -4.00/9 1} 68. c7 {(c6-c7 Rc4-c1 Rf3-f5 Rc1xc7 Kb6xc7 Kd2-e3
Rf5-f3+ Ke3-d4 Rf3-f4+ Kd4-c5 Rf4xh4 Kc5-d5 Rh4-h7) +7.10/14 1} Rc1
{(Rc4-c1) -6.05/8 1} 69. Rf5 {(Rf3-f5 Rc1xc7 Kb6xc7 Kd2-e3 Rf5-f1 Ke3-d4
Kc7-d6 Kd4-e3) +7.15/15 1} Rxc7 {(Rc1xc7) -7.15/8 1} 70. Kxc7 {(Kb6xc7
Kd2-e3 Rf5-f6 Ke3-d4 Kc7-d6 Kd4-e3 Rf6-f5 Ke3-e2 Rf5-f3 Ke2-d1 Rf3-f1+
Kd1-d2 Rf1-f4 Kd2-e3 Kd6-e5 Ke3-d2 Ke5-d4 Kd2-c2) +7.45/19 1} Kc1 {(Kd2-c1)
-7.35/9 1} 71. Rd5 {(Rf5-d5 Kc1-b1 Rd5-d1+ Kb1-a2 Rd1-d4 Ka2-a1 Rd4-f4
Ka1-b2 Rf4xh4 Kb2-a1) +17.15/22 1} Kb1 {(Kc1-b1) -7.45/9 1} 72. Rc5
{(Rd5-c5) +17.20/21 1} Ka1 {(Kb1-a1) -7.60/10 1} 73. Rc2 {(Rc5-c2 Ka1-b1
Rc2-c4 Kb1-a2 Rc4-a4+ Ka2-b1 Ra4xh4 Kb1-a2 g2-g4 Ka2-a1 g4-g5 Ka1-b1 g5-g6
Kb1-a1 g6-g7 Ka1-b1 Rh4-d4 Kb1-c1 g7-g8Q Kc1-b2) +17.40/26 1} Kb1 {(Ka1-b1)
-7.60/11 1} 74. Rc4 {(Rc2-c4) +17.40/25 1} Ka2 {(Kb1-a2) -7.60/9 1} 75. Rc3
{(Rc4-c3 Ka2-b2 g2-g4 Kb2xc3 g4-g5 Kc3-b2 g5-g6 Kb2-c2 g6-g7 Kc2-c3 g7-g8Q
Kc3-d4 Qg8-g1+ Kd4-e4) +11.05/20 1} Ka1 {(Ka2-a1) -7.60/10 1} 76. Rb3
{(Rc3-b3 Ka1-a2 Rb3-b6 Ka2-a1 Kc7-c6 Ka1-a2 Kc6-c5 Ka2-a1 Kc5-c4 Ka1-a2)
+M8/17 1} Ka2 {(Ka1-a2) -7.60/11 1} 77. Rc3 {(Rb3-c3) +11.05/20 1} Ka1
{(Ka2-a1) -7.60/10 1} 78. Rb3 {(Rc3-b3) +M8/18 1} Ka2 {(Ka1-a2) -7.60/11 1}
79. Rc3 {(Rb3-c3) +11.05/20 1 3-fold repetition} 1/2-1/2

[/pgn]

I tested again the same game but in certain moment change a move so the game will not be the same

If I let the engine play from that position, wins without problem

I tt_free(); after ucinewgame, here is the code:

Code: Select all

uint8_t i;
for &#40;i = 4; i <= board->fiftymove; i += 2&#41; &#123;
	if &#40;board->key == board->move_history&#91;board->ply - i&#93;.key&#41; &#123;
		return true;
	&#125;
&#125;
In the board_s struct I have a history game where I set the zobrist key of the position (in MakeMove)

Is this a problem with the TT??
AndrewGrant
Posts: 1754
Joined: Tue Apr 19, 2016 6:08 am
Location: U.S.A
Full name: Andrew Grant

Re: Added repetition detection but in some games repeats

Post by AndrewGrant »

Is there ever a case when the keys do not switch back and forth from white move to black move? If you are using NULL move pruning what do you do with your board_history?
#WeAreAllDraude #JusticeForDraude #RememberDraude #LeptirBigUltra
"Those who can't do, clone instead" - Eduard ( A real life friend, not this forum's Eduard )
User avatar
cdani
Posts: 2204
Joined: Sat Jan 18, 2014 10:24 am
Location: Andorra

Re: Added repetition detection but in some games repeats

Post by cdani »

tttony wrote: I tt_free(); after ucinewgame, here is the code:

Code: Select all

uint8_t i;
for &#40;i = 4; i <= board->fiftymove; i += 2&#41; &#123;
	if &#40;board->key == board->move_history&#91;board->ply - i&#93;.key&#41; &#123;
		return true;
	&#125;
&#125;
If I understand well, this code is not in the search, but is a previous verification before entering the search. So it forces a draw immediately somehow.

The typical way of finding a repetition is inside the search, where you put the evaluation to 0, withouth forcing anything, so letting the engine decide if the 0 is good enough to repeat the position, treating the 0 as any other evaluation.
tttony
Posts: 268
Joined: Sun Apr 24, 2011 12:33 am

Re: Added repetition detection but in some games repeats

Post by tttony »

AndrewGrant wrote:Is there ever a case when the keys do not switch back and forth from white move to black move? If you are using NULL move pruning what do you do with your board_history?
Forgot to add that also added null move, in the MakeNullMove() I set to zero the history move, here's how I execute null move in the search:

Code: Select all

if &#40;true
	&& board->ply > 0
	&& board->move_history&#91;board->ply - 1&#93;.move // <-- Here's = 0 so will not do consecutive null moves
	&& !inCheck
	&& !MateScore&#40;beta&#41;
	&& depth >= 4
	&& currEval >= beta
	&& popCount&#40;Occupancy&#40;board&#41;) > 3 // more than 3 pieces in the board
	&& &#40;board->bb->pieces&#91;WHITE&#93;&#91;PAWN&#93; || board->bb->pieces&#91;BLACK&#93;&#91;PAWN&#93;)) // at least one pawn present in the board
&#123;
	uint8_t R = depth > 6 ? 4 &#58; 3;

	MakeNullMove&#40;board&#41;;
	score = -search&#40;-beta, -beta + 1, depth - R - 1, board, params, 0, new_pv&#41;;
	UnmakeNullMove&#40;board&#41;;
	 
	if &#40;params->stop&#41; &#123;
		return 0;
	&#125;

	if &#40;score >= beta&#41; &#123;
		tt_save&#40;board->key, board->ply, hash, beta, NO_MOVE, depth, HASH_BETA, 0&#41;;
		return beta;
	&#125;
&#125;
I just hash the side and en passant in the MakeNull() function, also I set the key(that is also used to check repetition),

In the UnmakeNull() I just set the presvious key without hashing again

Code: Select all

void MakeNullMove&#40;board_s *board&#41; &#123;

	ASSERT&#40;CheckBoard&#40;board&#41;);
	ASSERT&#40;!SqAttacked&#40;board->kingsq&#91;board->side&#93;, Enemy&#40;board->side&#41;, board&#41;);

	undo_s *undo_history		= board->move_history + board->ply;

	undo_history->key			= board->key;
	undo_history->move			= NO_MOVE;
	undo_history->fiftymove		= board->fiftymove;
	undo_history->enpassant		= board->enpassant;
	undo_history->castleflag	= board->castleflag;

	board->ply++;

	if &#40;board->enpassant != NO_SQ&#41; &#123;
		HASH_EP;
		board->enpassant = NO_SQ;
	&#125;
		
	board->side ^= 1;
	HASH_SIDE;

	ASSERT&#40;CheckBoard&#40;board&#41;);
	ASSERT&#40;board->ply >= 0 && board->ply < MAX_DEPTH&#41;;

&#125; // MakeNullMove

void UnmakeNullMove&#40;board_s *board&#41; &#123;

	ASSERT&#40;CheckBoard&#40;board&#41;);

	board->ply--;

	board->key = board->move_history&#91;board->ply&#93;.key;
	board->castleflag = board->move_history&#91;board->ply&#93;.castleflag;
	board->fiftymove = board->move_history&#91;board->ply&#93;.fiftymove;
	board->enpassant = board->move_history&#91;board->ply&#93;.enpassant;

	//board->move_history&#91;board->ply&#93;.move = -2;

	board->side ^= 1;

	ASSERT&#40;CheckBoard&#40;board&#41;);
	ASSERT&#40;board->ply >= 0 && board->ply < MAX_DEPTH&#41;;

&#125; // TakeNullMove

@Daniel
, sorry the repetition code it's inside a function and the search code start like this:

Code: Select all

int32_t search&#40;...) &#123;

if (!inCheck && depth <= 0&#41; &#123;
	return qsearch&#40;alpha, beta, 1, board, params, pv&#41;;
&#125;

CheckInputAndTime&#40;params&#41;;
if &#40;params->stop&#41; 
	return 0;

if &#40;board->ply&#41; *pv = 0;
++params->nodes;

if &#40;board->ply && &#40;Repetition&#40;board&#41; || board->fiftymove > 99&#41;) &#123;
	return 0;
&#125;

if &#40;board->ply > MAX_DEPTH - 1&#41; &#123;
	return eval&#40;board&#41;;
&#125;

// after this I check the TT
AndrewGrant
Posts: 1754
Joined: Tue Apr 19, 2016 6:08 am
Location: U.S.A
Full name: Andrew Grant

Re: Added repetition detection but in some games repeats

Post by AndrewGrant »

I don't see any modifications to move_history in your MakeNullMove and UnmakeNullMove functions. Which means that your Move history could look something like this

White Move, Black Move, (NULL, but not actually in the array), Black Move

Then, when you jump around by 2's to check repetition, you don't get an accurate picture.
#WeAreAllDraude #JusticeForDraude #RememberDraude #LeptirBigUltra
"Those who can't do, clone instead" - Eduard ( A real life friend, not this forum's Eduard )
tttony
Posts: 268
Joined: Sun Apr 24, 2011 12:33 am

Re: Added repetition detection but in some games repeats

Post by tttony »

AndrewGrant wrote:I don't see any modifications to move_history in your MakeNullMove and UnmakeNullMove functions. Which means that your Move history could look something like this

White Move, Black Move, (NULL, but not actually in the array), Black Move

Then, when you jump around by 2's to check repetition, you don't get an accurate picture.
Ok, I'm missing something here, you right the history will have a key but with no move, so it does not make sense to check for repetitions where null moves are in the history

What do you mean with:
I don't see any modifications to move_history in your MakeNullMove and UnmakeNullMove functions
Here the move_history array it's modified, in MakeNull()

Code: Select all

undo_s *undo_history      = board->move_history + board->ply;

undo_history->key         = board->key;
undo_history->move         = NO_MOVE;
undo_history->fiftymove      = board->fiftymove;
undo_history->enpassant      = board->enpassant;
undo_history->castleflag   = board->castleflag; 
The idea is to create another array with key to check only for repetitions, and this array will not filled in MakeNull(), something like this:

Code: Select all

board->rep_history&#91;board->rep_ply++&#93; = board->key
tttony
Posts: 268
Joined: Sun Apr 24, 2011 12:33 am

Re: Added repetition detection but in some games repeats

Post by tttony »

Can't edit, I saw in your engine that you actually check if the position has repeated two times:

Code: Select all

int nRepetition = 0;
const end = max&#40;0, ply - stack&#91;ply&#93;.fifty&#41;;
for &#40;int i = ply - 4; i >= end; i -= 2&#41; &#123;
      if &#40;stack&#91;i&#93;.key.code == stack&#91;ply&#93;.key.code && ++nRepetition >= 2&#41; return Result.repetitionDraw;
&#125;
First time I see this, most of the engines returns true if the position has the same key

In your null move:

Code: Select all

update&#40;0&#41;;
    s = -&#945;&#946;(-&#946;, -&#946; + 1, d - r&#41;;
restore&#40;0&#41;;
You don't have a dedicated function to make the null move, just set to zero the move and inside you check for if (move != 0) {, but you set the stack key, before move != 0

Code: Select all

Stack *n = &stack&#91;ply + 1&#93;;

n.key.update&#40;this, move&#41;;
n.pawnKey.update&#40;this, move&#41;;
n.castling = u.castling;
n.enpassant = Square.none;
n.fifty = cast &#40;byte&#41; &#40;u.fifty + 1&#41;;
So the null move key can be added to the history?
Sven
Posts: 4052
Joined: Thu May 15, 2008 9:57 pm
Location: Berlin, Germany
Full name: Sven Schüle

Re: Added repetition detection but in some games repeats

Post by Sven »

Tony, when making the null move you could simply do this:
- store all position state information as usual for a later undo,
- switch the side to move (and increment your ply counter if you have one),
- store the resulting hash key in your key history,
- and reset the fifty moves counter to 0 since the null move should be considered irreversible (at least that's what I do and what many others do).

That way you do not mess up your key history but you also avoid to check for a repetition of a position that occurred prior to any null move since you only need to go backwards as many plies as the fifty moves counter indicates when comparing the current hash key with earlier keys.
tttony
Posts: 268
Joined: Sun Apr 24, 2011 12:33 am

Re: Added repetition detection but in some games repeats

Post by tttony »

Tony, when making the null move you could simply do this:
- store all position state information as usual for a later undo,
- switch the side to move (and increment your ply counter if you have one),
- store the resulting hash key in your key history,
- and reset the fifty moves counter to 0 since the null move should be considered irreversible (at least that's what I do and what many others do).

That way you do not mess up your key history but you also avoid to check for a repetition of a position that occurred prior to any null move since you only need to go backwards as many plies as the fifty moves counter indicates when comparing the current hash key with earlier keys.
The three fold works but in some games like the one in the first post, end in three fold rep, if I go infinite in that position, the engine wins

Even in this position detect the repetition and returns zero:

http://www.talkchess.com/forum/viewtopi ... 19&t=59841

Code: Select all

FEN&#58; qq3rk1/ppp1p2p/3p2p1/8/8/3Q4/2Q3PK/8 w - - 0 1 

Skiull 0.2 x64 popcnt&#58;
   1	00&#58;00	          99	99	-10,50	Qd3-c4+
   2	00&#58;00	         371	371	-10,50	Qd3-c4+ d6-d5
   3	00&#58;00	       3.560	3.560	-10,50	Qd3-c4+ d6-d5 Qc4xc7
   4	00&#58;00	      10.564	10.564	-10,70	Qd3-c4+ Rf8-f7 Qc4xc7 e7-e5
   5	00&#58;00	      28.452	28.452	-10,50	Qd3-c4+ Rf8-f7 Qc4xc7 e7-e5 Qc7xb8+
   6	00&#58;00	      76.426	76.426	-10,50	Qd3-c4+ Rf8-f7 Qc4xc7 e7-e5 Qc7xb8+ Qa8xb8
   7	00&#58;00	     127.406	7.962.875	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+
   8	00&#58;00	     139.769	8.735.563	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+
   9	00&#58;00	     193.643	12.102.688	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+
  10	00&#58;00	     219.235	13.702.188	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+
  11	00&#58;00	     423.657	9.013.979	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+
  12	00&#58;00	     511.466	10.882.255	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+
  13	00&#58;00	   1.507.466	9.663.244	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+
  14	00&#58;00	   1.853.548	9.130.778	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+
  15	00&#58;06	  50.550.937	8.351.385	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+
  16	00&#58;12	 105.795.584	8.199.937	 0,00	Qd3xg6+ h7xg6 Qc2xg6+ Kg8-h8 Qg6-h6+ Kh8-g8 Qh6-g6+

So it "works", the problem is to detect the bug that makes repeat in win positions in some games, I have to collect all those games and test it

Now thanks to your comment I reset the fifty rule in MakeNullMove(), I don't remember which but some engines don't reset the fifty rule

Now the MakeNullMove is like this:

Code: Select all

void MakeNullMove&#40;board_s *board&#41; &#123;

	undo_s *undo_history		= board->move_history + board->ply;
	undo_history->key		= board->key;
	undo_history->move		= NO_MOVE;
	undo_history->fiftymove	= board->fiftymove;
	undo_history->enpassant	= board->enpassant;

	board->fiftymove = 0;
	++board->ply;
	if &#40;board->enpassant != NO_SQ&#41; &#123;
		HASH_EP;
		board->enpassant = NO_SQ;
	&#125;
	board->side ^= 1;
	HASH_SIDE;
&#125;