Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Low depth gives blunder #38

Open
tissatussa opened this issue Dec 4, 2024 · 8 comments
Open

Low depth gives blunder #38

tissatussa opened this issue Dec 4, 2024 · 8 comments

Comments

@tissatussa
Copy link

tissatussa commented Dec 4, 2024

While testing v1.4.1 (i didn't encounter any illegal move yet!) the following position arose, Woodpusher playing White :

woodpusher-Ne5-blunder

Here 18.Ne5 was played, which was a blunder : after 18...Rxe5 (the 'normal' Nxe5 was even better) 19.dxe5? Nc3! White's Queen is attacked and also the King by Qxg2# ! Woodpusher decided Ne5 after 6.3s at depth 6. Indeed, it would have taken too long in this 5m+3s game to reach depth 7, but then the engine would have found Re1 bestmove. For a human these kind of tactics are not difficult to spot, but only reaching depth 6 isn't enough, this position is a good example i think.

You should find some method to increase the search depth, probably by improving pruning somehow. And do you use Quiescence Search ? That might have avoided this blunder.


[Event "engine vs engine"]
[Site "Holland @ https://lichess.org/50JJB8mt "]
[Date "2024.12.04"]
[Round "?"]
[White "Woodpusher v1.4.1 PR37"]
[Black "Skiull v0.6"]
[Result "0-1"]
[ECO "A05"]
[GameDuration "00:14:45"]
[Opening "Reti Opening"]
[PlyCount "144"]
[TimeControl "300+3"]

1. Nf3 {+0.28/7 5.5s} Nf6 {-0.10/11 11s} 2. d4 {0.00/6 1.8s} d5 {-0.15/11 10s}
3. Nc3 {+0.02/6 4.1s} e6 {-0.10/10 10s} 4. e3 {+0.33/5 1.3s}
Bd7 {-0.10/11 10.0s} 5. Bd3 {+0.07/6 4.5s} Bb4 {-0.15/10 9.8s}
6. a3 {+0.16/6 5.2s} Bxc3+ {+0.10/11 9.6s} 7. bxc3 {+0.44/7 3.6s}
Nc6 {+0.10/11 9.5s} 8. O-O {+0.25/6 3.8s} O-O {+0.05/11 9.3s}
9. Bb2 {+0.26/6 3.1s} Ne4 {0.00/11 9.2s} 10. Nd2 {+0.43/5 1.9s}
f5 {+0.05/11 9.0s} 11. Rc1 {+0.43/4 1.3s} Re8 {+0.05/10 8.9s}
12. c4 {+0.45/6 3.7s} Qg5 {+0.05/10 8.7s} 13. cxd5 {+0.52/4 1.7s}
exd5 {+0.05/11 8.6s} 14. c4 {+0.55/6 6.4s} Be6 {+0.05/11 8.4s}
15. Nf3 {+0.47/7 12s} Qg6 {-0.05/10 8.3s} 16. cxd5 {+0.41/6 4.4s}
Bxd5 {+0.05/11 8.2s} 17. Bb5 {+0.41/4 2.2s} Rad8 {+0.05/10 8.0s}
18. Ne5 {+0.50/6 6.3s} Rxe5 {+1.30/10 7.9s} 19. f3 {-0.87/5 3.9s}
Re7 {+1.30/10 7.8s} 20. fxe4 {-0.89/6 9.1s} fxe4 {+1.30/10 7.7s}
21. Qa4 {-0.86/6 10s} a6 {+1.30/9 7.5s} 22. Bc4 {-0.82/6 4.2s}
Bxc4 {+1.25/9 7.4s} 23. Qxc4+ {-0.61/7 5.8s} Qe6 {+1.25/8 7.3s}
24. Qxe6+ {-0.63/7 8.5s} Rxe6 {+1.15/9 7.2s} 25. Rc5 {-0.66/6 3.5s}
Rg6 {+1.00/8 7.1s} 26. Rf4 {-0.27/7 7.0s} b6 {+0.40/8 7.0s}
27. Rcf5 {+0.08/8 20s} Re6 {+0.10/10 6.9s} 28. d5 {+0.56/8 16s}
g6 {0.00/11 6.8s} 29. dxe6 {+0.49/8 7.9s} gxf5 {0.00/11 6.7s}
30. Rxf5 {+0.44/10 22s} Rd1+ {0.00/11 6.6s} 31. Rf1 {+0.49/11 22s}
Rxf1+ {+0.05/13 6.5s} 32. Kxf1 {-0.03/11 23s} Ne7 {+0.10/13 6.4s}
33. a4 {+0.68/9 9.4s} Nd5 {+0.35/12 6.4s} 34. Kf2 {-0.02/9 14s}
Kf8 {+0.55/11 6.3s} 35. Ba3+ {-0.16/9 8.8s} Ke8 {+0.80/11 6.2s}
36. a5 {-0.40/10 9.4s} bxa5 {+1.00/12 6.1s} 37. Bc5 {-0.37/9 7.6s}
h5 {+1.00/11 6.0s} 38. Kg3 {-0.31/10 10s} a4 {+1.05/12 6.0s}
39. Kh4 {-0.55/10 11s} a3 {+1.00/12 5.9s} 40. Bxa3 {-0.14/8 1.5s}
Nxe3 {+1.20/13 5.8s} 41. Kg3 {-0.43/8 1.6s} Nc2 {+1.05/12 5.7s}
42. Bc5 {-0.32/8 1.1s} Ne1 {+1.60/12 5.7s} 43. Kh4 {-1.03/8 1.4s}
e3 {+2.55/11 5.6s} 44. Bb4 {-1.62/8 1.4s} Nd3 {+2.95/14 5.5s}
45. Ba5 {-1.93/8 1.2s} e2 {+2.95/12 5.5s} 46. g4 {-1.98/9 2.5s}
hxg4 {+3.75/13 5.4s} 47. Kxg4 {-2.14/10 3.7s} e1=Q {+3.85/13 5.4s}
48. Bxe1 {-2.34/11 2.4s} Nxe1 {+3.80/14 5.3s} 49. h4 {-2.97/12 2.4s}
Ke7 {+2.85/14 5.2s} 50. Kf5 {-2.38/13 3.2s} Nf3 {+2.85/13 5.2s}
51. h5 {-2.38/12 2.5s} Nd4+ {+2.55/12 5.1s} 52. Kg6 {-2.60/12 3.2s}
a5 {+4.00/13 5.1s} 53. h6 {-3.44/12 3.2s} Nxe6 {+4.25/12 5.0s}
54. h7 {-3.44/12 4.8s} Nf8+ {+5.45/13 5.0s} 55. Kf5 {-5.37/13 3.0s}
Nxh7 {+5.55/13 4.9s} 56. Ke4 {-5.48/12 4.0s} Nf6+ {+5.65/13 4.9s}
57. Kd4 {-5.43/11 3.1s} a4 {+5.90/14 4.8s} 58. Kc3 {-5.54/11 4.1s}
Nd5+ {+11.50/13 4.8s} 59. Kb2 {-6.42/12 4.0s} c5 {+11.00/14 4.7s}
60. Ka3 {-6.74/13 3.8s} Nb6 {+13.25/14 4.7s} 61. Ka2 {-6.95/12 3.9s}
c4 {+13.45/14 4.7s} 62. Kb2 {-11.25/12 4.5s} Ke6 {+13.50/13 4.6s}
63. Kb1 {-12.80/12 5.3s} c3 {+15.35/13 4.6s} 64. Ka2 {-12.80/11 2.9s}
Nd5 {+20.70/12 4.5s} 65. Ka3 {-13.41/12 4.8s} Ne3 {+M19/12 4.5s}
66. Ka2 {-13.44/12 8.1s} c2 {+M15/12 4.5s} 67. Kb2 {-13.17/10 8.3s}
a3+ {+M13/10 4.4s} 68. Kxa3 {-13.38/11 8.6s} c1=Q+ {+M9/9 4.4s}
69. Kb4 {-M8/9 3.0s} Kd5 {+M7/8 4.3s} 70. Kb5 {-M6/7 0.53s} Qb1+ {+M5/9 4.3s}
71. Ka5 {-M4/5 0.19s} Kc5 {+M3/9 4.3s} 72. Ka6 {-M2/3 0.055s}
Qb6# {+M1/9 4.3s, Black mates} 0-1
@sictransit
Copy link
Owner

I do use quiescence search, but I will add your game as a test and get back to you. Right now I've implemented NegaScout which makes the engine spend more time where it (hopefully) belongs. At least I've seen an improvement in how it plays.

The position is quite complex:

8 · · · r r · k ·
7 p p p · · · p p
6 · · n · · · q ·
5 · B · b · p · ·
4 · · · P n · · ·
3 P · · · P N · ·
2 · B · · · P P P
1 · · R Q · R K ·
  a b c d e f g h
Hash: 10788696342539649284
FEN: 3rr1k1/ppp3pp/2n3q1/1B1b1p2/3Pn3/P3PN2/1B3PPP/2RQ1RK1 w - - 2 18

At depth 7 it reconsiders and plays d1e2 instead, which is not bad. However, that's after 39 seconds. I still have some work to do.

position fen 3rr1k1/ppp3pp/2n3q1/1B1b1p2/3Pn3/P3PN2/1B3PPP/2RQ1RK1 w - - 2 18
go
info depth 1 seldepth 11 nodes 496 nps 13777 hashfull 0 score cp 14 time 44 pv d1c2
info depth 2 seldepth 16 nodes 4194 nps 28924 hashfull 0 score cp 17 time 149 pv f3e5 g6h6
info depth 3 seldepth 15 nodes 7410 nps 32933 hashfull 0 score cp 44 time 230 pv f3e5 g6h6 d1c2
info depth 4 seldepth 19 nodes 82128 nps 84320 hashfull 1 score cp 45 time 979 pv f3e5 g6e6 d1c2 d5b3
info depth 5 seldepth 20 nodes 182999 nps 122900 hashfull 6 score cp 29 time 1494 pv f3e5 e4c3 e5g6 c3d1 b5c6
info depth 6 seldepth 23 nodes 840476 nps 208813 hashfull 36 score cp 29 time 4030 pv f3e5 e4c3 e5g6 c3d1 b5c6 b7c6
info depth 7 seldepth 27 nodes 11352832 nps 70798 hashfull 485 score cp 19 time 39033 pv d1e2 e4g5 f3g5 g6g5 g2g3

@tissatussa
Copy link
Author

The position is quite complex

yes, and the move Ne5 is crucial, it involves delicate captures.

while letting v1.4.1 play more 5m+3s games against other engines, i encountered one 'disconnection', see your log and the CuteChess one : Woodpusher-v1.4.1-PR37-connection-stalls-vs-Rocinante.zip

i thought i made a screenshot, the CuteChess log doesn't show what the GUI displayed : "connection stalls".

@tissatussa
Copy link
Author

I do use quiescence search

Oh well, i just saw that 'feature list' in the README ..

what about move ordering ? Is it important ? Anyway, when NOT ALL leaves in the variation tree are evaluated, will first-do-captures-and-checks help us quicker find a 'sound' bestmove, or more often ? I once did a rebuild of the TSCP engine in Python and Nim, just to learn some, and it can't reach depth 7 when many pieces are on the board .. it has a simple alpha-beta pruning and some PSQ tables. I guess other functions must be added to archive higher depth in same time - although i wonder how to avoid stripping valuable variations .. you know what i mean - it's an ART :-)

6-was-9.mp4

@tissatussa
Copy link
Author

Another "connection stalls" ..

Woodpusher-v1 4 1-PR37-connection-stalls-vs-GK

Here the logs : Woodpusher-v1.4.1-PR37-connection-stalls-vs-GK.zip

@sictransit
Copy link
Owner

Yeah! It is apparent I need to rewrite the UCI interface. I tried to make it more synchronous to avoid those illegal moves, but now it says it is still busy when it receives a new command immediately after it send its bestmove. Note that everything happens the same millisecond. That shouldn't be a problem and I'm sure the busy flag I introduced would have reset 1 ms later or so. I'll look into it. A UCI command queue is probably the way to go, instead of ignoring them in a busy state.

Thank you!

2024-12-06 12:44:03.492 +01:00 [INF] Sent: bestmove a5a6
2024-12-06 12:44:03.492 +01:00 [INF] Received: position startpos moves g1f3 d7d5 d2d4 c8f5 g2g3 e7e6 f1g2 b8c6 e1g1 f8e7 c1e3 g8f6 b1c3 f6g4 e3f4 g7g5 f4d2 c6b4 a2a3 b4c2 a1c1 c7c5 c1c2 c5d4 f3d4 f5c2 d1c2 d8d7 h2h3 g4e5 e2e4 d5e4 c2e4 e5c4 d2c1 c4d6 e4e2 e8c8 d4f3 f7f6 e2c2 c8b8 f1d1 d7c8 a3a4 h7h6 c2g6 d8g8 g6h5 e6e5 c3d5 c8e6 d5e7 e6e7 c1e3 d6f5 e3d2 g8d8 h5g6 f5d4 h3h4 d4f3 g2f3 g5h4 g1g2 h6h5 a4a5 h4g3 f2g3 h5h4 g3g4 h4h3 g2h2 e7c5 h2h1 c5f2 g6f6 h8e8 f6f7 e5e4 d2f4 b8a8 d1d8 e8d8 f7b7 a8b7 f3e4 b7c8 f4d6 d8d6 e4b7 c8b7 a5a6 b7a6
2024-12-06 12:44:03.492 +01:00 [WRN] Engine is busy, ignoring command: position startpos moves g1f3 d7d5 d2d4 c8f5 g2g3 e7e6 f1g2 b8c6 e1g1 f8e7 c1e3 g8f6 b1c3 f6g4 e3f4 g7g5 f4d2 c6b4 a2a3 b4c2 a1c1 c7c5 c1c2 c5d4 f3d4 f5c2 d1c2 d8d7 h2h3 g4e5 e2e4 d5e4 c2e4 e5c4 d2c1 c4d6 e4e2 e8c8 d4f3 f7f6 e2c2 c8b8 f1d1 d7c8 a3a4 h7h6 c2g6 d8g8 g6h5 e6e5 c3d5 c8e6 d5e7 e6e7 c1e3 d6f5 e3d2 g8d8 h5g6 f5d4 h3h4 d4f3 g2f3 g5h4 g1g2 h6h5 a4a5 h4g3 f2g3 h5h4 g3g4 h4h3 g2h2 e7c5 h2h1 c5f2 g6f6 h8e8 f6f7 e5e4 d2f4 b8a8 d1d8 e8d8 f7b7 a8b7 f3e4 b7c8 f4d6 d8d6 e4b7 c8b7 a5a6 b7a6
2024-12-06 12:44:03.492 +01:00 [INF] Received: isready
2024-12-06 12:44:03.492 +01:00 [WRN] Engine is busy, ignoring command: isready

@tissatussa
Copy link
Author

..now it says it is still busy when it receives a new command immediately after it send its bestmove. Note that everything happens the same millisecond..

so, the logs were useful !

among chess engine programmers it seems rather common to use two threads : one for the calculation / evaluation and one to detect and handle commands, e.g. otherwise it's hard to react instantly when stop is given. Not all engines use 2 threads though, it should be possible to use just 1 thread, but i can't help you on that. Many solutions will be possible in software.

@sictransit
Copy link
Owner

OK! I think I nailed it. There were two problems:

  1. I thought the illegal moves were due to a timing bug, so I tried to fix that and introduced the stalling problem instead. Additionally that wasn't problem after all.
  2. The illegal move problem was due to some code I introduced a while ago. When the engine sees a possibility to get the game back to theory (i.e. the opening book) it would play a move to return to a known position. Unfortunately, the move it tried to play was for the opposite side.

Releasing v1.4.2 soon.

@tissatussa
Copy link
Author

i don't understand your second point : those "connection stalled" positions can not transpose into any opening position in the book, they're too far into the game !?
Anyhow, i will switch to using v1.4.2 and await an error (or not) and report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants