Giter Site home page Giter Site logo

ethereal's Issues

Ethereal exceeds time and looses

When using Ethereal with CuteChess in a tournament, the engine (v11.75) exceeds the clock time limit -- I tested 5 minutes for 40 moves -- and so it looses the game ?!

I don't know how CuteChess does instruct an engine to limit 40 moves in 5 min, because the UCI protocol only has "fixed depth" / "time per move" / "infinite" when calculating any FEN, but other engines do not seem to have this problem.

Add an Eval Cache

Going to be adding King-Safety soon. An Eval Cache will more valuable when the Evaluation process takes longer.

Clarify the Tuning system / settings

  • Depth 0 should actually correspond to Texel Tuning Proper (IE, no search)
  • Depth 0 should not care about the CLEARING setting, as its never used, simply a slowdown
  • The comment about CLEARING in texel.c is unclear, may suggest something other than intended.
  • Option to collect the phase from before or after resolution of the position.
  • No reason to have three sets of ENABLE_, collapse with macro magic into the header
  • Fix comment about scaling PawnValue[MG] to 100cp

syzygy

Hi Andy. Are you going to do support in syzygy in Ethereal?

Support MultiPV

It would be useful to find out more easily what Ethereal is thinking of multiple moves without having to manually check each one.

Crashing/losing connection/etc

Hi

Ran some mini-tournaments with 5 engines under CuteChess. Picking up some issue with Ethereal, so not sure if it's my setup, or something with CuteChess, or something with Ethereal. Don't have these issues with the other engines in the tests, but on the other hand, playing games between engines under PyChess does not produce same problems ... so I don't know.

Or maybe stockfish is somehow interfering with Ethereal?

Samples follow. Other games ended normally.

White "Ethereal"]
[Black "stockfish"]
[Result "0-1"]
[FEN "1rbqkbr1/1nppppn1/2pppp2/8/8/2PPPP2/1NPPPPN1/1RBQKBR1 w - - 0 1"]
[GameDuration "00:04:58"]
[GameEndTime "2019-11-05T11:33:20.066 SAST"]
[GameStartTime "2019-11-05T11:28:22.064 SAST"]
[PlyCount "8"]
[SetUp "1"]
[Termination "time forfeit"]
[TimeControl "40/240+5"]

  1. e4 {+0.07/25 17s} d5 {+0.08/27 23s} 2. d4 {+0.21/25 26s} Nd6 {-0.28/28 4.0s}
  2. e5 {+0.25/25 20s} fxe5 {0.00/25 10s} 4. dxe5 {+0.46/26 26s}
    Nc4 {+0.60/30 0s, White loses on time} 0-1
    ======================================

[White "stockfish"]
[Black "Ethereal"]
[Result "1-0"]
[FEN "1rbqkbr1/1nppppn1/2pppp2/8/8/2PPPP2/1NPPPPN1/1RBQKBR1 w - - 0 1"]
[GameDuration "00:07:02"]
[GameEndTime "2019-11-05T11:40:33.065 SAST"]
[GameStartTime "2019-11-05T11:33:30.068 SAST"]
[PlyCount "27"]
[SetUp "1"]
[Termination "time forfeit"]
[TimeControl "40/240+5"]

  1. d4 {+0.47/27 28s} e5 {-0.08/25 18s} 2. e4 {+0.51/27 2.0s} Ne6 {-0.19/25 8.2s}

  2. e3 {+0.29/26 0.41s} Ra8 {-0.28/25 18s} 4. Nd3 {+0.48/28 9.2s}
    c5 {-0.27/26 14s} 5. d5 {+0.75/22 4.1s} Ng7 {-0.35/24 22s} 6. c4 {+1.27/22 7.6s}
    Na5 {-0.30/23 3.2s} 7. Nb2 {+1.46/24 4.7s} e6 {-0.53/22 7.9s}

  3. Ra1 {+1.50/26 28s} c6 {-0.28/24 39s} 9. d3 {+1.76/20 4.0s} Bb7 {-0.58/23 21s}

  4. dxe6 {+1.37/24 14s} Nxe6 {-0.61/23 6.2s} 11. Bd2 {+1.56/23 0s}
    d5 {-0.79/24 22s} 12. Rh1 {+1.58/21 8.3s} Qb6 {-0.90/24 9.3s}

  5. Qc1 {+1.96/23 7.0s} Qd8 {-0.81/23 22s}

  6. Nh4 {+1.80/27 0s, Black loses on time} 1-0
    ==========================================
    [White "komodo-10-linux"]
    [Black "Ethereal"]
    [Result "1-0"]
    [FEN "1rbqkbr1/1nppppn1/2pppp2/8/8/2PPPP2/1NPPPPN1/1RBQKBR1 w - - 0 1"]
    [GameDuration "00:26:01"]
    [GameEndTime "2019-11-05T14:54:11.068 SAST"]
    [GameStartTime "2019-11-05T14:28:09.071 SAST"]
    [PlyCount "153"]
    [SetUp "1"]
    [Termination "time forfeit"]
    [TimeControl "40/240+5"]

  7. d4 {+0.20/22 11s} e5 {-0.08/25 19s} 2. Rh1 {0s} d5 {0.00/24 22s}

  8. Nd3 {+0.21/24 15s} e4 {-0.05/25 21s} 4. fxe4 {+0.31/22 13s}
    dxe4 {-0.16/26 16s} 5. Nc5 {0s} d5 {0.00/25 12s} 6. c4 {+0.57/23 1.1s}
    e5 {-0.10/24 14s} 7. Nxb7 {0s} Bxb7 {-0.01/25 13s} 8. Bb2 {+0.41/22 3.4s}
    Qd6 {0.00/24 16s} 9. c5 {+0.81/21 12s} Qe6 {-0.61/23 7.8s}

  9. Bc3 {+0.87/22 1.9s} Qf5 {-1.23/25 33s} 11. d3 {+1.15/20 9.3s}
    Ne6 {-0.76/24 21s} 12. Rb4 {+1.24/19 8.9s} Ng5 {-1.13/25 17s}

  10. Qb1 {+1.42/22 15s} Qc8 {-1.15/27 2.5s} 14. Qb2 {+1.40/22 18s}
    f5 {-1.51/25 20s} 15. Rh5 {0.001s} Be7 {-1.97/24 20s} 16. dxe5 {0.002s}
    Bxc5 {-2.00/24 16s} 17. Rb3 {0.003s} Bb6 {-1.76/24 16s} 18. Nf4 {+1.75/22 12s}
    Ne6 {-1.51/24 5.1s} 19. Rxf5 {+1.90/21 4.5s} c5 {-1.52/23 12s}

  11. Nh5 {+1.24/19 19s} Rg1 {-1.35/22 16s} 21. Nf6+ {+0.74/21 31s}
    Ke7 {-0.87/22 8.6s} 22. dxe4 {+0.50/21 7.1s} Ng7 {0.00/25 11s}

  12. Rf3 {+0.40/23 3.7s} dxe4 {0.00/27 8.0s} 24. Rg3 {+0.28/22 6.1s} Rxg3 {2.5s}

  13. fxg3 {+0.28/22 5.1s} Bc6 {0.00/29 2.8s} 26. g4 {0.00/23 20s} Qh8

  14. Bg2 {+0.25/22 13s} Ne6 28. Nh5 {-0.86/21 15s} Qh6 {+2.01/26 12s}

  15. Qc1 {-0.82/23 8.9s} Rg8 {+1.69/28 9.9s} 30. Nf6 {-1.57/26 30s} Rh8

  16. Nh5 {-2.07/24 13s} Qg5 {+3.47/27 9.2s} 32. Kf1 {-2.09/26 3.1s}
    Qxg4 {+3.49/27 4.0s} 33. Nf6 {-2.48/27 36s} Qf5+ 34. Kg1 {-2.07/24 4.4s}
    Qg5 {+3.69/31 1.9s} 35. Qe1 {-2.08/26 12s} Ba7 {+4.90/28 13s}

  17. Kf1 {-3.08/22 21s} c4 {+5.33/29 10.0s} 37. Bb4+ {-2.76/23 9.9s} Kd8

  18. Ra3 {-3.06/24 10s} Nf4 {+5.50/29 1.8s} 39. Qf2 {-3.13/26 13s}
    Bxe3 {+5.62/31 3.4s} 40. Nh7 {-3.30/26 9.4s} Qxg2+ {+5.59/30 7.0s} 41. Qxg2 {0s}
    Nxg2 {+5.71/31 13s} 42. Kxg2 {0.002s} Bd2 {+5.92/31 39s} 43. Ra6 {-3.14/27 11s}
    Bxb4 {+5.96/30 4.8s} 44. Rxc6 {-3.22/29 11s} Rxh7 {+5.98/30 10s}

  19. Rxc4 {0.001s} Ba5 {+6.00/29 35s} 46. Rxe4 {0.002s} Ke7 {+6.01/28 11s}

  20. Kg3 {-3.43/26 10s} Ke6 {+6.13/26 18s} 48. Re3 {-3.50/27 9.9s}
    Bb6 {+6.29/28 36s} 49. Rd3 {0.001s} Rh5 {+6.24/27 10s} 50. c4 {-3.83/26 15s}
    Rh1 {+6.47/25 11s} 51. Rf3 {-3.76/24 14s} Rg1+ {+7.03/26 9.2s}

  21. Kf4 {-4.04/27 0.28s} Rc1 {+7.16/26 17s} 53. Kg3 {-4.01/26 8.8s}
    Rxc4 {+7.48/26 5.5s} 54. Rf6+ {-4.33/26 2.8s} Kxe5 {+7.73/25 7.8s}

  22. Rxf7 {-3.28/22 4.8s} Re4 {+7.93/25 8.6s} 56. Rf8 {-3.99/24 13s}
    Kd5 {+10.03/25 31s} 57. Rd8+ {-4.23/26 8.4s} Kc4 {+11.19/24 15s} 58. Rd7 {0s}
    Rxe2 {+11.66/27 16s} 59. Kf3 {-11.87/27 15s} Re1 {+12.37/24 15s}

  23. Kg4 {-16.58/32 2.2s} c5 {+14.38/23 11s} 61. Rb7 {-17.03/34 12s}
    Kb5 {+22.73/23 11s} 62. Rb8 {-250.00/33 14s} c4 {1.1s} 63. Rc8 {-250.00/31 45s}
    Re3 64. Ra8 {-250.00/29 11s} c3 {+34.32/21 14s} 65. Ra2 {26s} Re1

  24. Kf5 {-250.00/24 9.3s} Kb4 {+31.10/23 15s} 67. Kg6 {-250.00/26 15s}
    Kb3 {+M35/25 15s} 68. Ra8 {23s} c2 {+M29/23 10s} 69. Rc8 {0.001s}
    Be3 {+M33/20 8.7s} 70. Kf5 {-M28/20 1.00s} c1=Q {+M23/9 5.0s} 71. Rxc1 {0s}
    Bxc1 {+M23/18 5.0s} 72. Kg6 {0.001s} Rf1 {+M17/18 5.0s} 73. Kh5 {-M16/30 1.7s}
    Rg1 {3.3s} 74. Kh4 {0.002s} Kc4 {+M13/19 6.7s} 75. Kh3 {0s} Kd3 {+M11/32 5.0s}

  25. Kh2 {-M10/99 1.8s} Be3 {3.2s} 77. Kh3 {0s, Black loses on time} 1-0
    ==================================================

[White "Ethereal"]
[Black "xiphos-sse"]
[Result "0-1"]
[FEN "1rbqkbr1/2nppn2/1pppppp1/8/8/1PPPPPP1/2NPPN2/1RBQKB1R b - - 1 1"]
[GameDuration "00:29:21"]
[GameEndTime "2019-11-05T01:08:02.075 SAST"]
[GameStartTime "2019-11-05T00:38:40.885 SAST"]
[PlyCount "209"]
[SetUp "1"]
[Termination "stalled connection"]
[TimeControl "40/300"]

1... Bb7 {-0.14/21 9.1s} 2. Bb2 {+0.21/20 7.9s} Bg7 {-0.21/22 12s}
3. e4 {+0.14/20 6.7s} e5 {-0.17/22 20s} 4. Bg2 {+0.11/20 8.8s} f5 {-0.17/25 13s}
5. Ra1 {+0.09/22 8.0s} Ne6 {-0.05/23 0.95s} 6. Bh3 {+0.32/21 7.2s}
f4 {-0.20/24 12s} 7. Bxe6 {+0.39/22 6.0s} dxe6 {-0.17/23 7.1s}
8. gxf4 {+0.41/23 0.63s} exf4 {-0.16/22 5.6s} 9. d4 {+0.58/23 3.7s}
Rh8 {-0.25/23 13s} 10. Rxh8+ {+0.69/22 9.5s} Bxh8 {-0.30/25 2.7s}
11. e3 {+0.47/24 5.8s} fxe3 {-0.14/24 1.8s} 12. Nxe3 {+0.43/23 5.6s}
Ra8 {-0.15/26 0.65s} 13. Ke2 {+0.44/25 5.8s} Rxa1 {-0.16/28 5.0s}
14. Qxa1 {+0.53/26 13s} Qa8 {-0.20/28 1.8s} 15. Qxa8+ {+0.61/26 4.5s}
Bxa8 {-0.20/26 3.3s} 16. Nd3 {+0.37/26 2.9s} g5 {-0.24/27 2.9s}
17. Nc4 {+0.35/25 7.6s} b5 {-0.14/26 9.7s} 18. Nb6 {+0.58/27 11s}
Bb7 {-0.05/24 5.4s} 19. c4 {+0.58/26 1.2s} bxc4 {-0.02/28 6.7s}
20. bxc4 {+0.44/27 0.35s} Kd8 {-0.10/28 17s} 21. Bc3 {+0.41/29 6.9s}
Kc7 {-0.20/23 0.72s} 22. Na4 {+0.63/29 8.6s} Bg7 {-0.17/24 0.22s}
23. Kf2 {+0.61/24 9.5s} Ba6 {-0.22/27 2.2s} 24. Nab2 {+0.49/26 10s}
Bc8 {-0.21/27 4.2s} 25. Nd1 {+0.58/25 7.7s} Nh6 {-0.20/25 4.1s}
26. Ba5+ {+0.62/24 11s} Kd7 {0.00/35 7.3s} 27. Bc3 {+0.63/25 0.47s}
Kc7 {0.00/42 6.1s} 28. Nb4 {+0.48/26 7.8s} Bd7 {-0.32/23 6.5s}
29. Ne3 {+0.47/25 2.5s} Kb6 {-0.23/25 7.1s} 30. Nd3 {+0.47/24 11s}
Be8 {-0.25/27 9.0s} 31. Nc5 {+0.52/27 2.4s} Bf7 {-0.22/27 7.7s}
32. Kg3 {+0.45/28 19s} Kc7 {-0.29/30 9.6s} 33. Na6+ {+0.44/25 16s}
Kb6 {-0.21/26 6.8s} 34. Nb4 {+0.44/26 0.59s} Bf6 {-0.31/28 7.4s}
35. Nd3 {+0.44/27 2.5s} Bh5 {-0.41/28 16s} 36. Nb4 {+0.44/26 14s}
Bf7 {0.00/42 7.3s} 37. Nd3 {+0.53/26 8.4s} Bh5 {0.00/50 8.4s}
38. Bb2 {+0.43/25 7.2s} Bg6 {-0.03/26 13s} 39. Ba1 {+0.40/24 5.0s}
Ka5 {-0.01/25 13s} 40. Bc3+ {+0.71/25 6.9s} Ka4 {-0.23/28 6.6s}
41. Kh2 {+0.52/24 5.5s} Kb3 {0.00/28 19s} 42. Nc1+ {+0.48/29 7.0s}
Ka4 {0.00/31 9.4s} 43. Kh3 {+0.39/27 16s} Bh5 {0.00/30 15s}
44. Kg3 {+0.29/29 23s} Bg7 {-0.06/33 46s} 45. Ne2 {+0.40/24 13s}
Kb3 {0.00/31 0.58s} 46. Nc1+ {+0.40/26 11s} Ka4 {0.00/66 5.4s}
47. Nc2 {+0.40/25 16s} Ng8 {0.00/28 9.6s} 48. Nd3 {+0.33/25 14s}
Nh6 {0.00/30 2.5s} 49. Nc1 {+0.20/26 15s} Ng8 {0.00/38 5.1s}
50. d3 {+0.22/25 3.6s} Nh6 {0.00/28 5.8s} 51. Kf2 {0.00/24 0.45s}
Be8 {+0.19/25 8.8s} 52. Bd2 {0.00/27 12s} Nf7 {+0.09/27 3.5s}
53. Ne2 {0.00/27 2.1s} Bd7 {+0.15/25 2.4s} 54. Ke1 {0.00/28 9.5s}
e5 {+0.22/27 12s} 55. d5 {0.00/28 7.0s} cxd5 {+0.22/27 14s}
56. cxd5 {0.00/28 7.9s} g4 {+0.33/25 3.9s} 57. fxg4 {0.00/30 1.5s}
Bxg4 {+0.25/24 2.4s} 58. Ne3 {0.00/31 5.6s} Bh3 {+0.35/25 1.6s}
59. Kd1 {0.00/26 7.9s} Ng5 {+0.43/27 11s} 60. Nc4 {-0.13/26 14s}
Bf6 {+0.40/28 5.1s} 61. Kc2 {-0.14/26 5.2s} Kb5 {+0.43/26 2.7s}
62. Nc3+ {-0.15/27 2.7s} Ka6 {+0.53/24 4.9s} 63. Be3 {-0.19/26 0.55s}
Nf3 {+0.38/24 10s} 64. Na2 {-0.20/28 0.64s} Nd4+ {+0.52/26 3.5s}
65. Kc3 {-0.15/27 1.2s} Bg4 {+0.42/26 5.2s} 66. Nb4+ {-0.13/28 8.5s}
Kb5 {+0.37/30 2.6s} 67. Bf2 {0.00/29 2.8s} Bg5 {+0.45/26 15s}
68. Nc2 {0.00/31 6.2s} Ne2+ {+0.51/27 3.6s} 69. Kb3 {0.00/33 3.8s}
Bf3 {+0.47/24 0.30s} 70. Nb4 {0.00/29 5.1s} Nd4+ {+0.52/24 3.7s}
71. Bxd4 {0.00/34 3.4s} Bd1+ {0.00/34 4.7s} 72. Nc2 {0.00/37 5.7s}
exd4 {0.00/40 3.2s} 73. Nb2 {0.00/39 3.7s} Bxc2+ {0.00/42 4.8s}
74. Kxc2 {0.00/39 0.25s} Kb4 {0.00/42 5.1s} 75. Nc4 {0.00/41 27s}
Kb5 {0.00/53 0.002s} 76. Kb3 {0.00/40 35s} Bf6 {0.00/54 8.3s}
77. Na3+ {+0.19/30 2.0s} Ka5 {0.00/53 7.1s} 78. Nc2 {6.5s} Kb5 {0.00/65 13s}
79. Nb4 Bg7 {0.00/51 9.7s} 80. Nc6 {+0.34/33 1.4s} e5 {0.00/59 16s} 81. Nd8
Bf8 {0.00/55 10s} 82. Ka2 {+0.34/29 23s} Kb4 {0.00/35 9.3s}
83. Kb2 {+0.34/28 59s} Bh6 {0.00/71 35s} 84. Ne6 {13s} Bd2 {0.00/50 6.6s}
85. Kc2 {+0.34/22 46s} Be3 {0.00/56 16s} 86. Nf8 {21s} Kb5 {0.00/47 6.1s}
87. Kb2 {27s} Kb4 {0.00/82 72s} 88. Kc2 {+0.34/21 3.9s} Bg5 {0.00/85 0.099s}
89. Ne6 {+0.34/26 28s} Be3 90. Ng7 {+0.34/18 3.7s} Bg5 {0.00/63 14s}
91. Kb2 {+0.34/18 3.7s} Bf4 {0.00/56 4.1s} 92. Kc2 {+0.34/30 3.4s}
Bg5 {0.00/99 0.050s} 93. Kb2 {+0.34/31 20s} Bf4 {0.00/71 8.4s}
94. Nf5 {+0.34/31 2.4s} Kc5 {0.00/42 5.6s} 95. Kb3 {9.8s} Bg5 {0.00/49 3.8s}
96. Ng7 {+0.34/27 13s} Bf6 {0.00/59 4.5s} 97. Ne6+ {+0.34/33 9.8s}
Kb5 {0.00/72 8.8s} 98. Nc7+ Kc5 {0.00/72 15s} 99. Ka4 Bh4 {0.00/46 2.6s}
100. Ne8 {5.0s} Bd8 {0.00/62 26s} 101. Ng7 {+0.34/36 0.74s} Kb6 {0.00/42 2.4s}
102. Kb4 {+0.34/32 0.67s} Be7 {0.00/63 1.8s} 103. Ne6 {+0.34/36 0.65s}
Bh4 {0.00/71 2.2s} 104. Nf8 {+0.34/37 5.4s} Be7 {0.00/69 2.9s} 105. Ne6 {1.5s}
Bh4 {White's connection stalls} 0-1

=========================================================

[White "Ethereal"]
[Black "stockfish"]
[Result "0-1"]
[FEN "1rbqkbr1/2nppn2/1pppppp1/8/8/1PPPPPP1/2NPPN2/1RBQKB1R b - - 1 1"]
[GameDuration "00:02:23"]
[GameEndTime "2019-11-05T02:26:01.063 SAST"]
[GameStartTime "2019-11-05T02:23:37.139 SAST"]
[PlyCount "15"]
[SetUp "1"]
[Termination "stalled connection"]
[TimeControl "40/300"]

1... Bg7 {-0.14/24 15s} 2. Ra1 {+0.20/21 8.4s} d5 {0.00/24 5.7s}
3. Bb2 {+0.32/20 6.7s} Nd6 {+0.46/22 2.0s} 4. e4 {+0.06/19 7.1s}
Kf7 {+0.56/23 6.9s} 5. f4 {+0.19/22 33s} Rh8 {+0.80/23 6.0s}
6. Rxh8 {0.00/21 6.0s} Qxh8 {+1.00/24 2.7s} 7. exd5 {+0.12/22 3.2s}
exd5 {+0.68/27 19s} 8. e4 {-0.10/23 8.1s}
c5 {+0.71/25 0s, White's connection stalls} 0-1

=====================================================

[White "stockfish"]
[Black "Ethereal"]
[Result "1-0"]
[FEN "1rbqkbr1/2nppn2/1pppppp1/8/8/1PPPPPP1/2NPPN2/1RBQKB1R b - - 1 1"]
[GameDuration "00:07:24"]
[GameEndTime "2019-11-05T02:33:31.063 SAST"]
[GameStartTime "2019-11-05T02:26:06.067 SAST"]
[PlyCount "32"]
[SetUp "1"]
[Termination "time forfeit"]
[TimeControl "40/300"]

1... Bg7 {-0.24/20 15s} 2. e4 {+0.73/25 24s} Ra8 {-0.20/19 11s}
3. Bg2 {+0.71/22 6.2s} Bb7 {-0.24/22 4.9s} 4. Bb2 {+0.49/22 14s}
e5 {-0.22/24 5.8s} 5. Kf1 {+0.46/20 1.1s} Ra2 {0.00/22 7.1s}
6. d4 {+0.77/22 4.3s} exd4 {+0.27/21 6.5s} 7. cxd4 {+0.48/22 0.50s}
f5 {+0.21/19 5.4s} 8. Qc1 {+0.24/25 36s} Nb5 {+0.23/22 17s}
9. Kg1 {+0.55/20 6.1s} e6 {+0.15/22 9.9s} 10. e3 {+0.07/23 18s}
Ra8 {+0.24/23 5.1s} 11. Nb4 {+0.31/23 15s} Qe7 {+0.42/21 8.6s}
12. Nbd3 {+0.28/23 2.2s} Rh8 {0.00/22 8.8s} 13. Rxh8+ {+0.40/20 2.1s}
Bxh8 {0.00/24 7.7s} 14. Bf1 {+0.60/24 5.9s} Ng5 {0.00/23 13s}
15. Kg2 {+0.70/23 8.4s} fxe4 {0.00/24 15s} 16. Nxe4 {+0.17/26 1.8s}
Nxe4 {-0.20/23 4.9s} 17. fxe4 {+0.09/24 0s, Black loses on time} 1-0

=============================================

[White "Ethereal"]
[Black "stockfish"]
[Result "0-1"]
[FEN "1rbqkbr1/1pnppnp1/2pppp2/8/8/2PPPP2/1PNPPNP1/1RBQKBR1 w - - 0 1"]
[GameDuration "00:16:12"]
[GameEndTime "2019-11-04T22:50:56.069 SAST"]
[GameStartTime "2019-11-04T22:34:43.124 SAST"]
[PlyCount "98"]
[SetUp "1"]
[Termination "time forfeit"]
[TimeControl "40/300"]

  1. Rh1 {+0.29/18 8.5s} Ra8 {-0.21/25 23s} 2. e4 {+0.23/21 14s}
    g5 {-0.25/24 5.8s} 3. b4 {+0.52/19 9.4s} d5 {-0.08/21 5.1s}
  2. exd5 {+0.36/21 7.7s} exd5 {-0.22/25 2.3s} 5. Bb2 {+0.44/22 5.0s}
    e5 {-0.21/21 7.6s} 6. Ra1 {+0.41/22 14s} Rxa1 {-0.12/20 2.4s}
  3. Qxa1 {+0.30/22 3.2s} Rh8 {-0.29/25 12s} 8. Rxh8 {+0.36/23 8.3s}
    Nxh8 {-0.12/24 3.5s} 9. g3 {+0.37/22 5.9s} Ng6 {0.00/24 18s}
  4. e4 {+0.46/23 7.5s} d6 {-0.16/24 0s} 11. Qa7 {+0.60/32 217s}
    Bg7 {-0.25/32 0.001s} 12. Ne3 {+0.68/13 0s} Kf8 {-0.27/27 7.5s}
  5. Bh3 {+1.44/1 0s} Ne7 {-0.21/26 5.4s} 14. Bxc8 {+1.39/1 0s}
    Qxc8 {-0.31/24 6.5s} 15. Kd1 Ke8 {-0.21/25 6.9s} 16. Kc2 {+1.21/1 0s}
    Qa8 {-0.09/24 2.0s} 17. Qxa8+ {+2.11/1 0s} Nxa8 {0.00/27 3.9s} 18. b5
    Nc7 {0.00/28 4.1s} 19. bxc6 {+1.41/1 0s} bxc6 {0.00/30 5.4s} 20. Ba3
    Nb5 {+0.35/27 5.1s} 21. Bb4 {+0.94/1 0s} Kd7 {+0.19/28 8.9s}
  6. Ba5 {+0.80/1 0s} d4 {+0.19/28 4.5s} 23. Nc4 {+0.05/1 0s} f5 {+0.23/28 7.2s}
  7. Nb6+ {+0.57/1 0s} Ke6 {+0.25/27 4.5s} 25. Nc4 {+0.40/1 0s}
    f4 {+0.52/27 9.3s} 26. gxf4 {+0.91/1 0s} gxf4 {+0.38/28 16s} 27. Ng4
    Ng6 {+0.33/28 5.8s} 28. Kd1 Bf6 {+0.50/27 9.5s} 29. Nxf6 {+0.67/1 0s}
    Kxf6 {+0.36/30 7.5s} 30. cxd4 Nxd4 {+0.09/35 9.2s} 31. Nxd6 Nxf3 {+0.09/36 4.9s}
  8. Ke2 {-0.20/1 0s} Nd4+ {+0.85/28 3.5s} 33. Kf2 {-1.04/1 0s}
    Nf8 {+0.92/32 3.9s} 34. Bd8+ {-0.07/1 0s} Ke6 {+0.94/36 7.5s} 35. Nc4
    Nd7 {+0.88/38 11s} 36. Ba5 Nc5 {+0.89/38 5.4s} 37. Nb2 Ncb3 {+0.89/40 8.1s}
  9. Bb6 c5 {+0.85/36 15s} 39. Ke1 Nc6 {+0.55/37 14s} 40. Kd1 Nb4 {+0.54/37 11s}
  10. Bd8 {-0.42/31 1.6s} Nd4 {+0.54/37 7.1s} 42. Bc7 {-0.44/30 0.29s}
    Nb3 {+0.54/38 15s} 43. Bd8 {-0.43/32 7.3s} Nc6 {+0.54/40 0s}
  11. Bh4 {-0.43/32 10.0s} Kf7 {+0.79/34 16s} 45. Kc2 {-0.69/29 7.0s}
    Nbd4+ {+0.88/33 0s} 46. Kd1 {-0.74/26 5.9s} Ne6 {+0.61/35 24s}
  12. Bf2 {-0.58/29 9.3s} Kf6 {+1.03/34 13s} 48. Na4 {-0.83/31 5.2s}
    Nb4 {+1.07/38 5.0s} 49. Ke2 {-0.88/31 6.5s}
    Nd4+ {+1.07/45 0s, White loses on time} 0-1

===============================================

[White "stockfish"]
[Black "Ethereal"]
[Result "1-0"]
[FEN "1rbqkbr1/1pnppnp1/2pppp2/8/8/2PPPP2/1PNPPNP1/1RBQKBR1 w - - 0 1"]
[GameDuration "00:01:03"]
[GameEndTime "2019-11-04T22:52:00.064 SAST"]
[GameStartTime "2019-11-04T22:50:56.079 SAST"]
[PlyCount "7"]
[SetUp "1"]
[Termination "stalled connection"]
[TimeControl "40/300"]

  1. Rh1 {+0.74/25 11s} Ra8 {-0.26/18 8.5s} 2. b3 {+0.68/26 10s}
    b5 {-0.24/20 6.4s} 3. e4 {+0.90/23 6.0s} e5 {-0.20/20 7.2s}
  2. e3 {+1.00/24 0s, Black's connection stalls} 1-0

==============================================

Draws and Blunders

8/2n5/2B5/8/5p1p/5P1P/5kP1/7K w - - 2 2 should be lost for white.

Forcing boardIsDrawn() to return 0 fixes it.

int boardIsDrawn(Board *board, int height) {

    // Drawn if any of the three possible cases
    return drawnByFiftyMoveRule(board)
        || drawnByRepetition(board, height)
        || drawnByInsufficientMaterial(board);
}

Forcing drawnByFiftyMoveRule() to return 0 does not fix it
Forcing drawnByRepetition() to return 0 DOES fix it
Forcing drawnByInsufficientMaterial to return 0 does not fix it

pawnAttacks colour inversion

Is this a bug or intentional?

 #define TB_PAWN_ATTACKS(square, color) (pawnAttacks((square), ~0ull, (!color)))

I don't understand. WHen I look at the definition of pawnAttacks() it looks correct (no colour inversion).

Unify Coding Standards

[X] attacks.c       [X] attacks.h       [X] bitboards.c
[X] bitboards.h     [X] board.c         [X] board.h
[X] evaluate.c      [X] evaluate.h      [X] history.c
[X] history.h       [X] masks.c         [X] masks.h
[X] move.c          [X] move.h          [X] movegen.c
[X] movegen.h       [X] movepicker.c    [X] movepicker.h
[X] psqt.c          [X] psqt.h          [X] search.c
[X] search.h        [X] syzygy.c        [X] syzygy.h
[X] texel.c         [X] texel.h         [X] thread.c
[X] thread.h        [X] time.c          [X] time.h
[X] transposition.c [X] transposition.h [X] types.h
[X] uci.c           [X] uci.h           [X] windows.c
[X] windows.h       [X] zobrist.c       [X] zobrist.h

SEE Pruning

Should SEE Pruning only be applied to movePicker.stage > STAGE_GOOD_NOISY? Is it trying to prune table move?

Ethereal unable to mate with N and B

at the end of the following engine-vs-engine game, Ethereal 11.57 evaluates the position as winning by +9, but it doesn't know how to mate with only knight and bishop .. it lets the opponent king go to the wrong corner .. the game ends with a stalemate .. in this theme game Black should be able to win :

[Event "engine vs engine - theme game"]
[Site "Hengelo, Holland - https://lichess.org/eSUK0nC1"]
[Date "2019.11.24"]
[White "asmFish 190518"]
[Black "Ethereal 11.57"]
[Result "1/2-1/2"]
[PlyCount "159"]
[SetUp "1"]
[TimeControl "40/300"]
[FEN "rnbqkbnr/ppp1ppp1/8/3p3p/3P1B2/4P3/PPP2PPP/RN1QKBNR b KQkq - 0 1"]

1...e5 2. Bxe5 f6 3. Bf4 g5 4. Be2 gxf4 5. Bxh5+ Ke7 6. exf4 c6 7. Qd3 Qd6 8. Bf3 Qxf4 9. Ne2 Qd6 10. h3 f5 11. c4 Nf6 12. cxd5 cxd5 13. O-O Nc6 14. Nbc3 a6 15. Rfe1 Kd8 16. Rad1 Ne4 17. Qc2 Bd7 18. Qb3 Ne7 19. g3 Bh6 20. Bg2 Rc8 21. Qxb7 Rb8 22. Qa7 Nc8 23. Nxe4 fxe4 24. Qc5 Rxb2 25. Qa5+ Ke8 26. Nc3 Rf8 27. Qxd5 Rfxf2 28. Qg8+ Qf8 29. Rxe4+ Ne7 30. Qxf8+ Kxf8 31. Rf1 Rxf1+ 32. Bxf1 Bd2 33. Ne2 Rxa2 34. Re5 a5 35. Nf4 a4 36. Ne6+ Bxe6 37. Rxe6 Bc3 38. Rf6+ Kg7 39. Rf7+ Kxf7 40. Bc4+ Kf6 41. Bxa2 Bxd4+ 42. Kg2 Nc6 43. Kf3 Nb4 44. Bc4 a3 45. Ke4 Bf2 46. g4 a2 47. g5+ Kxg5 48. Bxa2 Nxa2 49. Kd3 Kh4 50. Kc4 Kxh3 51. Kb3 Nc1+ 52. Kc2 Be3 53. Kc3 Kg4 54. Kc4 Kg5 55. Kd5 Kf5 56. Kd6 Bf4+ 57. Kd5 Be3 58. Kd6 Bf4+ 59. Kd5 Nb3 60. Kc4 Nd2+ 61. Kd4 Ke6 62. Kd3 Kd5 63. Ke2 Ke4 64. Kf2 Nb3 65. Kf1 Kf3 66. Kg1 Nd4 67. Kh1 Bg3 68. Kg1 Nf5 69. Kh1 Bf2 70. Kh2 Nd4 71. Kh1 Bg3 72. Kg1 Bf2+ 73. Kh2 Ne2 74. Kh1 Be3 75. Kh2 Bf2 76. Kh1 Be3 77. Kh2 Bf4+ 78. Kh1 Nd4 79. Kg1 Ne2+ 80. Kh1 Bg3 1/2-1/2

Support for "searchmoves"?

Hi Andy,

do y plan to support this?

go movetime 100 searchmoves f2f3 a2a3
bestmove e2e4 ponder c7c5

I use this for "alternative move" at picochess, which is a great feature in my eyes.

Jürgen

Resolve KNB v K endgames

Need to create special PSQT table for KNB v K endgame, and then apply it when this endgame is reached. I have no idea what % of games I draw when I could have won as a result of not having this, but I imagine it is a guaranteed ELO gain to implement it.

Modify reading UCI inputs

An issue while working on lucasarts/zinc made me realize that my program does not work properly when it receives a position fen command which has two spaces between 'fen' and the fen string. Additionally, UCI.c was kinda sloppy.

Ethereal kind of stops in some position

Hi.

Have a look at this:

uci
id name Ethereal 11.53
id author Andrew Grant & Laldon
option name Hash type spin default 16 min 1 max 65536
option name Threads type spin default 1 min 1 max 2048
option name MoveOverhead type spin default 100 min 0 max 10000
option name SyzygyPath type string default
option name SyzygyProbeDepth type spin default 0 min 0 max 127
option name Ponder type check default false
option name UCI_Chess960 type check default false
uciok
position fen 8/8/8/4B3/8/2N2K2/8/6k1 w - - 22 12
go depth 30
info depth 1 seldepth 1 score cp 900 time 0 nodes 6 nps 6000 tbhits 0 hashfull 0 pv f3f4
info depth 2 seldepth 2 score cp 915 time 0 nodes 25 nps 25000 tbhits 0 hashfull 0 pv f3e4 g1g2
info depth 3 seldepth 3 score cp 893 time 0 nodes 77 nps 77000 tbhits 0 hashfull 0 pv f3g3 g1f1 g3f4
info depth 4 seldepth 4 score cp 898 time 0 nodes 112 nps 112000 tbhits 0 hashfull 0 pv f3g3 g1f1 g3f4 f1g2
info depth 5 seldepth 6 score cp 901 time 0 nodes 357 nps 357000 tbhits 0 hashfull 0 pv f3e4 g1f1 e4d4 f1f2 d4d5
info depth 6 seldepth 7 score cp 949 time 0 nodes 952 nps 952000 tbhits 0 hashfull 0 pv f3e4 g1h1 e4d4 h1g1 c3d5 g1g2
info depth 7 seldepth 8 score cp 983 time 16 nodes 2525 nps 148000 tbhits 0 hashfull 0 pv e5g3 g1h1 c3d1 h1g1 d1e3 g1h1 f3e4
info depth 8 seldepth 11 score cp 959 time 16 nodes 3588 nps 211000 tbhits 0 hashfull 0 pv e5g3 g1h1 c3d1 h1g1 d1f2 g1f1 f2e4 f1g1
info depth 9 seldepth 10 score cp 994 time 16 nodes 5529 nps 325000 tbhits 0 hashfull 1 pv c3d1 g1f1 d1e3 f1g1 e5b8 g1h1 f3g3 h1g1 b8f4 g1h1
info depth 10 seldepth 13 score cp 976 time 31 nodes 12238 nps 382000 tbhits 0 hashfull 3 pv c3d1 g1f1 d1e3 f1g1 e5f4 g1h1 f3e2 h1g1 f4b8 g1h1 b8c7
info depth 11 seldepth 16 score cp 983 time 31 nodes 20418 nps 638000 tbhits 0 hashfull 3 pv c3d1 g1f1 d1e3 f1g1 e5f4 g1h1 f3e2 h1g1 f4b8 g1h1 e2e1 h1g1 b8f4 g1h1
info depth 12 seldepth 18 score cp 970 time 47 nodes 36195 nps 754000 tbhits 0 hashfull 5 pv e5g3 g1f1 c3d1 f1g1 d1e3 g1h1 f3e4 h1g1 e4f4 g1h1 f4f3 h1g1 f3e2 g1h1 e2f1
info depth 13 seldepth 23 score cp 967 time 62 nodes 56402 nps 895000 tbhits 0 hashfull 8 pv e5g3 g1f1 c3d1 f1g1 d1e3 g1h1 f3e4 h1g1 e4f4 g1h1 f4f3 h1g1 f3e2 g1h1 e2d3 h1g1 d3e4 g1h1 e4d5 h1g1 d5e6
info depth 14 seldepth 22 score cp 975 time 94 nodes 92657 nps 975000 tbhits 0 hashfull 13 pv e5g3 g1f1 c3d1 f1g1 d1e3 g1h1 g3f2 h1h2 e3d5 h2h3 d5f4 h3h2 f3e4 h2h1 e4d5 h1h2 d5e6 h2h1 f2a7 h1h2
info depth 15 seldepth 24 score cp 993 time 141 nodes 160610 nps 1131000 tbhits 0 hashfull 20 pv e5g3 g1f1 c3d1 f1g1 d1e3 g1h1 g3f2 h1h2 e3d5 h2h3 d5f4 h3h2 f3e4 h2h1 e4d5 h1h2 d5e6 h2h1 e6f7 h1h2 f7g7 h2h1 f2a7
info depth 16 seldepth 32 score cp 981 time 359 nodes 455951 nps 1266000 tbhits 0 hashfull 53 pv e5g3 g1f1 c3d1 f1g1 d1e3 g1h1 g3f2 h1h2 e3d5 h2h3 d5f4 h3h2 f3e4 h2h1 e4d5 h1h2 d5e6 h2h1 e6f7 h1h2 f7e7 h2h1 e7d6 h1h2 d6c7 h2h1 c7d7 h1h2

Then... nothing. Output just stops at depth 16. Ethereal process still at max cpu but it seems stuck. Same with go infinite.

perft segfaults

I was trying to run your perft.py script, to do some speed measures on #47. But it crashed. So I tried master, it also crashed. Here's the minimal reproduction with master:

ucinewgame
position fen 1r1qk2r/5ppp/Q2p4/6R1/4P1bq/2N5/P1P5/4K1N1 b k - 0 23
print
  |---|---|---|---|---|---|---|---|
8 | . | r | . | q | k | . | . | r |
  |---|---|---|---|---|---|---|---|
7 | . | . | . | . | . | p | p | p |
  |---|---|---|---|---|---|---|---|
6 | Q | . | . | p | . | . | . | . |
  |---|---|---|---|---|---|---|---|
5 | . | . | . | . | . | . | R | . |
  |---|---|---|---|---|---|---|---|
4 | . | . | . | . | P | . | b | q |
  |---|---|---|---|---|---|---|---|
3 | . | . | N | . | . | . | . | . |
  |---|---|---|---|---|---|---|---|
2 | P | . | P | . | . | . | . | . |
  |---|---|---|---|---|---|---|---|
1 | . | . | . | . | K | . | N | . |
  |---|---|---|---|---|---|---|---|
    A   B   C   D   E   F   G   H
fen: 1r1qk2r/5ppp/Q2p4/6R1/4P1bq/2N5/P1P5/4K1N1 b k - 0
perft 1
Segmentation fault (core dumped)

Testing of branch windows_numa

compile with Windows msys2 (gcc 8.2):

$ make
gcc -DNDEBUG -O3 -std=gnu11 -Wall -Wextra -Wshadow -march=native -flto *.c fathom/tbprobe.c -lpthread -lm -DUSE_POPCNT -msse3 -mpopcnt -o Ethereal
windows.c: In function 'bestGroup':
windows.c:39:25: warning: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'void (*)()' [-Wcast-function-type]
   fun1_t fun1 = (fun1_t)(void(*)())GetProcAddress(k32, "GetLogicalProcessorInformationEx");
                         ^
windows.c:39:17: warning: cast between incompatible function types from 'void (*)()' to 'int (*)(LOGICAL_PROCESSOR_RELATIONSHIP,  struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *, DWORD *)' {aka 'int (*      )(enum _LOGICAL_PROCESSOR_RELATIONSHIP,  struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *, long unsigned int *)'} [-Wcast-function-type]
   fun1_t fun1 = (fun1_t)(void(*)())GetProcAddress(k32, "GetLogicalProcessorInformationEx");
                 ^
windows.c: In function 'bindThisThread':
windows.c:103:25: warning: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'void (*)()' [-Wcast-function-type]
   fun2_t fun2 = (fun2_t)(void(*)())GetProcAddress(k32, "GetNumaNodeProcessorMaskEx");
                         ^
windows.c:103:17: warning: cast between incompatible function types from 'void (*)()' to 'int (*)(USHORT,  struct _GROUP_AFFINITY *)' {aka 'int (*)(short unsigned int,  struct _GROUP_AFFINITY *)'} [-Wcas      t-function-type]
   fun2_t fun2 = (fun2_t)(void(*)())GetProcAddress(k32, "GetNumaNodeProcessorMaskEx");
                 ^
windows.c:104:25: warning: cast between incompatible function types from 'FARPROC' {aka 'long long int (*)()'} to 'void (*)()' [-Wcast-function-type]
   fun3_t fun3 = (fun3_t)(void(*)())GetProcAddress(k32, "SetThreadGroupAffinity");
                         ^
windows.c:104:17: warning: cast between incompatible function types from 'void (*)()' to 'int (*)(void *, const GROUP_AFFINITY *, struct _GROUP_AFFINITY *)' {aka 'int (*)(void *, const struct _GROUP_AFFI      NITY *, struct _GROUP_AFFINITY *)'} [-Wcast-function-type]
   fun3_t fun3 = (fun3_t)(void(*)())GetProcAddress(k32, "SetThreadGroupAffinity");
                 ^

functionality seems ok: 100% cpu is used with numa branch when all threads (80) are used,
with master windows show max cpu-load for ethereal 50,7%

Ethereal should attempt to find a shorter mate in Syzygy positions

    // If the root position can be found in the DTZ tablebases,
    // then we simply return the move recommended by Syzygy/Fathom.

The current code ensure that draws stay draws and wins stay wins, but it's pretty sad to see Ethereal make a mate announcement with 7 or 8 pieces on the board, then take 15 more moves to mate because DTZ is followed in 6-men syzygy positions.

Noise move picker on ProbCut

Can you use noise move picker on ProbCut? Seems like you could save a static exchange evaluation call since it is already called on MovePicker with a threshold. Something like this:

initNoiseMovePicker(&movePicker, thread, rBeta - eval);
or if rBeta - eval can be negative:

initNoiseMovePicker(&movePicker, thread, MAX(0, rBeta - eval));

and remove the SEE inside ProbCut loop.

Assertion hit when using TBs

Assertion is here

This line is NOT in Ronald's tb/master branch. I've reached out to him to ask if the assertion was placed there in error.

Steps to reproduce:
With a debug compile...

setoption name SyzygyPath value <path>
position fen 1R6/4k3/7P/P2p4/1PK3p1/8/8/r7 w - - 0 53
go infinite

Also, it appears that if I cap TB_LARGEST at 5, the assertion is never hit. Which would give evidence to this being an artifact from a time where Fathom could only probe 5 piece positions. (I'm not sure if Fathom was ever in that state, however ....)

Ethereal 11.11 loosing its thinking time

Hello Mr.,
I found Ethereal 11.11 on the internet, and when I create an engine match with time control 40 Moves in 30 Minutes reapiting, for first 40 moves Ethereal doesn't have this problem, but in second intermediar time (moves from 41 to 80) I saw that Ethereal remains with less than 10 seconds for I think 14 or 15 moves.
This situation happened more than once.
Thanks.

Evaluate draws

Using several function instead of popcount should give a small speed improvement.

Rework the move selection process

evaluateMoves & getNextMove are the next step in terms of raw performance. Cutting that down to a staged move generation of sorts would likely be faster.

The heuristic for move values is also pretty awful. Likely can find a better way of doing things, in addition to a speed up.

OS

Hi

Is this Windows-only?

Thanks, Ian

Margins for SEE pruning

No real issue but maybe worth to investigate:

I compared the see pruning margings that are used for quiet and tacticle moves in different engines (to get an idea what is worth testing in my engine):

Laser:

  • quiet: -24 * pruneDepth * pruneDepth
  • tacticle: -100 * depth

SF:

  • quiet: -29 * lmrDepth * lmrDepth
  • tacticle: -PawnValueEg * depth

Ethereal:

  • quiet: -80 * depth
  • tacticle: -18 * depth * depth

Xiphos:

  • quiet: -15 * _sqr(depth - 1)
  • tacticle: -100 * depth

Yours is the only that uses squared depth for tacticle moves instead of quiet moves. Have you tested the other way round?

Cleanup for struct board

board->pieceBitBoards ---> board->pieces
board->colourBitBoards ---> board->colours

remove all magic nums in index pieceBitBoards
actually keep track of the 50 move rule.....
among other things.

Store Principle Variations

Should not be any issues with the Transposition Table cutting off PV-lines, due to a Fruit trick to not use Tables for cut-offs in PV-Nodes (Costs a few Elo points). Should be simple to save the PV.

native windows threads

It is a real to compile Ethereal with Windows "native" Clang, MSVC or Intel Compiler
But it is a one problem - posix threads
If You have "windows.c" and "windows.h", could it possible to implement more portable solution for threads?
I never used threads into Pure C, but there is portable example for C++ below which works on Windows32/64, Linux, FreeBSD and Solaris as well:

thread.h:

#ifndef _EXT_THREAD_H
#define _EXT_THREAD_H

#ifdef WIN32
#include <windows.h>
#else
#include <pthread.h>
#include <signal.h>
#endif

namespace ext {

#ifdef WIN32
typedef HANDLE ThreadType;
#else
typedef pthread_t ThreadType;
#endif

class Thread {
public:
  Thread() {}
  virtual ~Thread();
 
  void Start();

  virtual void Execute() = 0;


  void Join();

  void Kill();

private:
  ThreadType __handle;

  Thread(const Thread&);
  void operator=(const Thread&);
};

} // ext

#endif

thread.cpp:

#include "thread.h"

namespace ext {

static void ThreadCallback(Thread* who) {
#ifndef WIN32
  int old_thread_type;
  pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old_thread_type);
#endif
  who->Execute(); 
}

#ifdef WIN32

Thread::~Thread() {
  CloseHandle(__handle);
}

void Thread::Start() {
  __handle = CreateThread(
    0, 0, 
    reinterpret_cast<LPTHREAD_START_ROUTINE>(ThreadCallback), this,
    0, 0
  );
}

void Thread::Join() {
  WaitForSingleObject(__handle,  INFINITE);
}

void Thread::Kill() {
  TerminateThread(__handle, 0);
}

#else

Thread::~Thread() {
}

extern "C"
typedef void *(*pthread_callback)(void *);

void Thread::Start() {
  pthread_create(
    &__handle, 0, 
    reinterpret_cast<pthread_callback>(ThreadCallback), 
    this
  );
}

void Thread::Join() {
  pthread_join(__handle, 0);
}

void Thread::Kill() {
  pthread_cancel(__handle);
}

#endif

} // ext

Example for one thread:

#include <iostream>
#include "thread.h"

class MyThread: public ext::Thread {
public:
  MyThread() : __done(false) {}
  virtual void Execute() {
    __done = true;
  }
  bool done() const { return __done; }
private:
  bool __done;
};

int main(int argc, char* argv[]) {
  MyThread thread; 
  std::cout << "Thread status before: " << thread.done() << std::endl;
  thread.Start();
  thread.Join();
  std::cout << "Thread status after: " << thread.done() << std::endl;
}

Example for 10 threads:

#include <vector>
#include <iostream>
#include "thread.h"

class MyThread: public ext::Thread {
public:
  MyThread(int id) : __id(id), __done(false) {}
  virtual void Execute() {
    if (__id != 3)
      __done = true;
  }
  bool done() const { return __done; }
private:
  int __id;
  bool __done;
};

typedef std::vector<MyThread*> Threads;

int main(int argc, char* argv[]) {
  std::vector<MyThread*> threads;

  for (int i = 0; i < 10; i++)
    threads.push_back(new MyThread(i));
 
  for (Threads::iterator i = threads.begin(); i != threads.end(); i++)
    (*i)->Start();
 
  for (Threads::iterator i = threads.begin(); i != threads.end(); i++)
    (*i)->Join();
 
  for (Threads::iterator i = threads.begin(); i != threads.end(); i++)
    std::cout << (*i)->done() << " ";
  std::cout << std::endl;
 
  for (Threads::iterator i = threads.begin(); i != threads.end(); i++)
    delete *i;
}

50-move mate delivery

Ethereal is wrong -- if mate has been delivered, there is no draw by fifty move rule.

we already have the inCheck flag. We can use genAllLegalMoves() as a quick hack ... At some point we should have a moveIsLegal function ...

Random vs random vs random

I made an experiment and matched "EtherealTrueRandom" vs "Teki Random Mover" (see https://github.com/Mk-Chan/Teki/tree/v0.1) and expected them to be very evenly matched, they are both random movers after all. Instead, I got the following:

Score of EtherealTrueRandom (8.97) vs Teki: 1265 - 638 - 8097 [0.531] 10000
Elo difference: 21.81 +/- 2.95
Finished match

So, as per your advice, I contacted Manik and asked him to look at your code and compare it to Ethereal. Here's what he has to say:

It seems Andrew is using movelist[rand() % size] to get a random move. The problem is that this is not truly random. My random function uses c++11s standard library uniform integer random distribution which has been shown to be much closer to a real uniformly random distribution. Source: https://channel9.msdn.com/Events/GoingNative/2013/rand-Considered-Harmful

Technical explanation:
Because size is not always a multiple of the range of rand() [which by itself is a bad rng by virtue of being linear congruential in glibc], rand() % size does not resolve to an integral number of sets of [0, size). The last set(for the [RANDMAX - size + 1, RANDMAX] will have less of a range and thus reduced randomness. This slightly favors moves in the earlier part of the movelist, which, judging by ethereal random's movegen are pawn moves. My suspicion is that ethereal moves pawns and queens a lot more than Teki.

Regards,
Manik

I also made another experiment, I matched EtherealTrueRandom against itself for 100k games and looked at the ECO openings distribution, here's the result:

Games = 100000 ( no result = 0, FEN tags = 0 )
Players = 1 ( clusters = 1 )
Date Range: 2018.03.09 - 2018.03.09

Games with: WhiteElo = 0 BlackElo = 0 BothElos = 0

White Wins = 7789 ( 7.79 % )
Draws = 84413 ( 84.41 % )
Black Wins = 7798 ( 7.8 % )
White Pct = 50.0 %
Black Pct = 50.0 %

ECO: Total = 100000 A: 94732 B: 4477 C: 504 D: 287 E: 0
PlyCount: Total = 100000 Range: 4-865 Average = 340.21 StdDev = 112.12

finished: be sure to rename/copy outSummary

There's very little variation. Then I did the same with Teki and there's little variation too, but it's a bit better:

Games = 100000 ( no result = 0, FEN tags = 0 )
Players = 1 ( clusters = 1 )
Date Range: 2018.03.09 - 2018.03.09

Games with: WhiteElo = 0 BlackElo = 0 BothElos = 0

White Wins = 8973 ( 8.97 % )
Draws = 82274 ( 82.27 % )
Black Wins = 8753 ( 8.75 % )
White Pct = 50.11 %
Black Pct = 49.89 %

ECO: Total = 100000 A: 90834 B: 781 C: 4178 D: 4207 E: 0
PlyCount: Total = 100000 Range: 6-901 Average = 357.18 StdDev = 154.9

finished: be sure to rename/copy outSummary

I don't know if you're using random generation for anything in the "real" version of Ethereal, but if you are, maybe this will help you make it better :)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.