In this position Skipper played invalid move Nf6-e4. Any clue ?
[d] 2Q3k1/6p1/5n2/3b1P1p/7P/8/8/4K3 b - - 79 91
[pgn]
[Event "Computer Chess Game"]
[Site "HP"]
[Date "2016.02.07"]
[Round "-"]
[White "Fairy-Max 4.8S"]
[Black "SkipperWinb"]
[Result "1-0"]
[TimeControl "120"]
[Annotator "1. +0.09 1... -0.01"]
1. c4 {+0.09/8} Nc6 {-0.01/15 2.5} 2. Nf3 {+0.08/8 2.0} h6 {+0.02/15 2.4}
3. Nc3 {+0.10/8 1.5} Nf6 {+0.17/13 2.4} 4. d4 {+0.02/8 1.9} d6
{-0.07/13 2.3} 5. h4 {+0.04/8 3} Bf5 {-0.08/12 2.3} 6. Qb3 {+0.15/8 1.8} b6
{-0.20/12 2.3} 7. Bf4 {+0.15/8 2.3} Na5 {-0.10/12 2.2} 8. Qd1 {-0.26/8 6}
Qd7 {+0.00/12 2.1} 9. b4 {-0.18/8 1.9} Nc6 {-0.12/13 2.1} 10. Qa4
{-0.05/8 1.7} e5 {+0.05/12 2.1} 11. dxe5 {-0.01/8 2.1} dxe5 {-0.07/12 2.0}
12. Rd1 {+0.04/8 2.5} Qe6 {-0.18/12 2.0} 13. Nxe5 {+0.04/8 3} Bxb4
{-0.24/12 2.0} 14. Nxc6 {+0.13/8 1.9} Bxc3+ {-0.05/11 1.9} 15. Bd2
{+0.22/8 1.4} Bxd2+ {-0.30/11 1.8} 16. Rxd2 {-0.18/9 1.9} Qe4
{-0.20/11 1.8} 17. Nb8+ {+0.50/7 1.1} Ke7 {-0.30/9 2.0} 18. Rd3
{+0.60/8 1.6} Be6 {-0.27/10 1.9} 19. Nc6+ {+0.56/8 3} Kf8 {+0.07/11 1.7}
20. e3 {+0.11/8 1.3} Bxc4 {+0.10/11 1.7} 21. Rd4 {+1.10/10 1.9} Bxf1
{-0.46/12 2.0} 22. Rxe4 {+1.10/10 1.3} Bxg2 {-0.59/13 2.1} 23. Qb4+
{+1.67/10 2.2} Kg8 {+0.00/12 1.9} 24. Ne7+ {+1.65/10 1.3} Kf8
{+0.00/14 1.9} 25. Ng6+ {+2.35/9 0.9} Kg8 {+0.00/14 1.8} 26. Re5
{+2.31/10 1.3} Bxh1 {-0.51/12 1.8} 27. Nxh8 {+2.13/10 1.5} Kxh8
{-0.50/15 1.9} 28. Qc4 {+2.08/10 1.0} Kg8 {-0.50/13 1.7} 29. Qxc7
{+2.11/10 2.0} Bf3 {-0.58/12 1.7} 30. a4 {+2.25/9 1.0} a6 {-0.56/11 1.7}
31. Rf5 {+2.41/9 0.8} Be4 {-1.28/14 1.6} 32. Rf4 {+2.44/10 1.0} Rf8
{-1.33/15 1.5} 33. Qc4 {+2.61/10 1.9} b5 {-1.32/14 1.5} 34. axb5
{+2.94/12 1.1} axb5 {-1.37/14 1.5} 35. Qxb5 {+2.97/12 1.5} Rd8
{-1.56/13 1.4} 36. f3 {+3.01/10 1.4} Bd5 {-1.65/13 1.3} 37. Rd4
{+3.15/11 1.2} Rd7 {-1.67/15 1.3} 38. Qc5 {+3.18/11 1.2} Be6 {-1.64/15 1.4}
39. Qc8+ {+3.18/12 3} Kh7 {-1.49/15 1.3} 40. Rxd7 {+3.00/12 0.8} Nxd7
{-1.53/15 1.3} 41. Qc2+ {+3.00/11 0.8} Kg8 {-1.53/13 0.8} 42. f4
{+3.04/12 1.4} f5 {-1.38/14 0.8} 43. e4 {+3.12/13 0.7} fxe4 {-1.11/14 0.9}
44. Qxe4 {+3.12/13 0.9} Bg4 {-1.11/12 1.0} 45. Qd5+ {+3.39/11 1.3} Kf8
{-1.42/11 0.7} 46. f5 {+3.43/12 0.6} Nf6 {-1.31/11 0.7} 47. Qc5+
{+3.38/12 1.3} Kg8 {-1.37/14 0.7} 48. Qc4+ {+3.17/13 0.5} Kh7
{-1.37/15 0.7} 49. Qf4 {+2.99/14 0.8} Kg8 {-1.39/13 0.7} 50. Qf2
{+3.05/13 0.7} Kh7 {-1.33/14 0.7} 51. Qf1 {+3.01/12 0.6} h5 {-1.39/15 0.7}
52. Qd3 {+3.32/14 0.7} Kg8 {-1.39/13 0.7} 53. Qc4+ {+3.22/13 1.0} Kh8
{-1.38/13 0.8} 54. Qb5 {+3.24/12 0.5} Bf3 {-1.30/14 0.8} 55. Qb8+
{+3.14/12 0.7} Kh7 {-1.44/15 0.6} 56. Qg3 {+3.13/13 0.5} Bd5 {-1.39/13 0.6}
57. Qg6+ {+3.16/15 0.6} Kh8 {-1.40/16 0.6} 58. Qg1 {+3.06/12 0.7} Kg8
{-1.40/14 0.6} 59. Qh2 {+3.14/10 0.4} Kh7 {-1.40/12 0.6} 60. Qg3
{+3.03/13 0.6} Kg8 {-1.40/13 0.6} 61. Qb8+ {+3.14/12 0.8} Kf7
{-1.49/11 0.6} 62. Qa7+ {+3.25/11 0.4} Kg8 {-1.44/11 0.6} 63. Qe7
{+3.12/12 0.4} Kh7 {-1.49/13 0.5} 64. Qe3 {+3.09/11 0.4} Kh8 {-1.49/13 0.5}
65. Qc5 {+3.08/12 1.0} Kh7 {-1.49/14 0.6} 66. Qb5 {+2.96/13 0.9} Kg8
{-1.49/13 0.5} 67. Qe2 {+3.09/12 2.2} Kf7 {-1.49/12 0.6} 68. Qe5
{+3.16/9 0.3} Kg8 {-1.49/13 0.5} 69. Qd6 {+3.11/11 0.4} Kf7 {-1.49/12 0.5}
70. Qc7+ {+3.19/10 0.3} Kg8 {-1.49/13 0.5} 71. Qd8+ {+3.19/15 6} Kh7
{-1.49/13 0.5} 72. Qa5 {+3.04/15 3} Kh8 {-1.49/13 0.5} 73. Qd2
{+3.08/10 0.3} Kh7 {-1.49/14 0.5} 74. Qg5 {+3.01/12 0.2} Kg8 {-1.49/14 0.5}
75. Qf4 {+3.10/11 0.2} Kf7 {-1.49/11 0.5} 76. Qd4 {+3.22/9 0.3} Kg8
{-1.40/11 0.4} 77. Qd3 {+3.12/11 0.4} Kh7 {-1.49/12 0.4} 78. Qf1
{+3.06/9 0.3} Kg8 {-1.49/12 0.4} 79. Qb5 {+3.10/12 0.3} Kf7 {-1.41/11 0.4}
80. Qc5 {+3.17/11 0.2} Kg8 {-1.50/12 0.4} 81. Qc7 {+3.12/11 0.3} Kh7
{-1.49/13 0.4} 82. Qe7 {+3.07/11 0.3} Kg8 {-1.49/12 0.4} 83. Qe5
{+3.12/8 0.2} Kf7 {-1.49/12 0.4} 84. Qd6 {+3.11/9 0.4} Kg8 {-1.49/13 0.4}
85. Qb4 {+3.09/11 0.3} Kf7 {-1.50/11 0.4} 86. Qf4 {+3.10/10 0.2} Kg8
{-1.49/12 0.4} 87. Qd4 {+3.11/12 0.3} Kh7 {-1.49/13 0.4} 88. Qb4
{+3.06/11 0.4} Kh6 {-1.52/12 0.4} 89. Qc3 {+3.14/10 0.1} Kh7 {-1.50/13 0.4}
90. Qc2 {+3.05/11 0.1} Kg8 {-1.50/12 0.3} 91. Qc8+ {+3.12/11 0.2}
{Xboard: Forfeit due to invalid move: f6e4 (f6e4) res=23} 1-0
[/pgn]
Invalid move
Moderators: hgm, Rebel, chrisw
-
- Posts: 1334
- Joined: Sun Jul 17, 2011 11:14 am
Re: Invalid move
Logically that would mean you've got issues with your in-check detection routine, no?
Matthew:out
Matthew:out
Some believe in the almighty dollar.
I believe in the almighty printf statement.
I believe in the almighty printf statement.
-
- Posts: 7218
- Joined: Mon May 27, 2013 10:31 am
Re: Invalid move
It has always allowed to capture the king.
Only for extensions it checks if king can be captured.
Something else but related:
I never trusted this code after the move loop
And it used to be:
But first code is more efficient.
By the way bug is not reproducible (of course).
Code: Select all
if (capture is King)
{
bestMove = move;
NodeCount++;
return ABSearch.MATE_SCORE - plyCount + 1;
}
Only for extensions it checks if king can be captured.
Something else but related:
I never trusted this code after the move loop
Code: Select all
if (Value <= -(ABSearch.MATE_SCORE - plyCount))
{
if (Value == -(ABSearch.MATE_SCORE - plyCount)
&&
!CanCaptureKing((ColorSign)(-curPlayer), Board.GetBits(ChessPiece.Kind.King, (ColorSign)(curPlayer)), null))
return 0;
return Value;
}
Code: Select all
if (Value <= -(ABSearch.MATE_SCORE - plyCount))
{
if (MateDetection(null) == CPosition.MateType.STALEMATE)
{
return 0;
}
else return Value;
}
By the way bug is not reproducible (of course).
-
- Posts: 2821
- Joined: Fri Sep 25, 2015 9:38 pm
- Location: Sortland, Norway
Re: Invalid move
Do the GUI allow king captures
-
- Posts: 7218
- Joined: Mon May 27, 2013 10:31 am
Re: Invalid move
No they should not. Perhaps Skippers GUI does sometimes when something is wrong. Why do you ask ?
I remember Skipper used to play an invalid move if it is almost checkmate. But in this position that is not the case or it must search very deep.
I remember Skipper used to play an invalid move if it is almost checkmate. But in this position that is not the case or it must search very deep.
-
- Posts: 759
- Joined: Fri Jan 04, 2013 4:55 pm
- Location: Nice
Re: Invalid move
Update bug thenHenk wrote:It has always allowed to capture the king.
Code: Select all
if (capture is King) { bestMove = move; NodeCount++; return ABSearch.MATE_SCORE - plyCount + 1; }
Only for extensions it checks if king can be captured.
Something else but related:
I never trusted this code after the move loop
And it used to be:Code: Select all
if (Value <= -(ABSearch.MATE_SCORE - plyCount)) { if (Value == -(ABSearch.MATE_SCORE - plyCount) && !CanCaptureKing((ColorSign)(-curPlayer), Board.GetBits(ChessPiece.Kind.King, (ColorSign)(curPlayer)), null)) return 0; return Value; }
But first code is more efficient.Code: Select all
if (Value <= -(ABSearch.MATE_SCORE - plyCount)) { if (MateDetection(null) == CPosition.MateType.STALEMATE) { return 0; } else return Value; }
By the way bug is not reproducible (of course).
-
- Posts: 7218
- Joined: Mon May 27, 2013 10:31 am
Re: Invalid move
What do you mean with "update bug" ?
-
- Posts: 759
- Joined: Fri Jan 04, 2013 4:55 pm
- Location: Nice
Re: Invalid move
When our bugs are not reproducible , it must be a problem during the search or make and unmake move or more insidious..Henk wrote:What do you mean with "update bug" ?
I think if you have a bug in your king in check routine you could reproduce it
-
- Posts: 4052
- Joined: Thu May 15, 2008 9:57 pm
- Location: Berlin, Germany
- Full name: Sven Schüle
Re: Invalid move
@Henk: If skipper plays an illegal root move, as you have described, then you could track it like this:
Add debugging code only for the root node (plyCount == 0 I guess). The effort is negligible so you could leave it in for a while. So if you are at the root then go through the whole move list that you have just generated in a conservative way (not optimized for efficiency but clear and safe, and also not basing on "king capture" but on the usual legality detection mechanisms) to identify all illegal moves, and save this information as a list of booleans (legal/illegal) where the list index corresponds to the index of the move in your regular move list. This additional list could be a global array (rootMoveIsLegal[]). To do this correctly you will probably also need to find out "in a conservative way" whether the moving side is currently in check (same here: only for root node - "global variable" isInCheckAtRoot).
Then continue with the normal move loop. In the loop body you should be able to tell whether the move that you have just tried was illegal or not (in your case of a king-capture engine I would assume you can tell it by looking at the returned subtree score). Now when being in the move loop of the root node this information must match the "conservative" legal/illegal flag that you have saved in the beginning. If it doesn't match then the last subtree has returned wrong information. This could still go unnoticed in the context of playing a move in the game since it could either be a legal root move that is wrongly classified as "illegal" (then you might just miss to play a better move if this root move would be the best move), or an illegal move that does not become new best move (then it does not affect the move decision). Now you could raise an exception and maybe dump some relevant information. Play hundreds or thousands of fast games with this instrumented version to see whether you can catch the problem. Save the games automatically! If the problem occurs you now have data to reproduce it, attach the debugger and find the root cause.
Add debugging code only for the root node (plyCount == 0 I guess). The effort is negligible so you could leave it in for a while. So if you are at the root then go through the whole move list that you have just generated in a conservative way (not optimized for efficiency but clear and safe, and also not basing on "king capture" but on the usual legality detection mechanisms) to identify all illegal moves, and save this information as a list of booleans (legal/illegal) where the list index corresponds to the index of the move in your regular move list. This additional list could be a global array (rootMoveIsLegal[]). To do this correctly you will probably also need to find out "in a conservative way" whether the moving side is currently in check (same here: only for root node - "global variable" isInCheckAtRoot).
Then continue with the normal move loop. In the loop body you should be able to tell whether the move that you have just tried was illegal or not (in your case of a king-capture engine I would assume you can tell it by looking at the returned subtree score). Now when being in the move loop of the root node this information must match the "conservative" legal/illegal flag that you have saved in the beginning. If it doesn't match then the last subtree has returned wrong information. This could still go unnoticed in the context of playing a move in the game since it could either be a legal root move that is wrongly classified as "illegal" (then you might just miss to play a better move if this root move would be the best move), or an illegal move that does not become new best move (then it does not affect the move decision). Now you could raise an exception and maybe dump some relevant information. Play hundreds or thousands of fast games with this instrumented version to see whether you can catch the problem. Save the games automatically! If the problem occurs you now have data to reproduce it, attach the debugger and find the root cause.
-
- Posts: 20943
- Joined: Mon Feb 27, 2006 7:30 pm
- Location: Birmingham, AL
Re: Invalid move
You are REALLY going about this in the wrong way. This is NOT the kind of thing you want to ask others to solve. If you don't understand how your tree search works, progress is going to be impossible. You can't just try this, try that, and keep whatever seems fastest or whatever. You really do have to organize yourself here and develop a plan for progress. First goal is to make whatever you have work with 100% correctness. Don't change/add a thing until you reach this point. If you are tweaking, tuning and modifying something that is inherently broken, you will be forever debugging old problems...Henk wrote:In this position Skipper played invalid move Nf6-e4. Any clue ?
[d] 2Q3k1/6p1/5n2/3b1P1p/7P/8/8/4K3 b - - 79 91
[pgn]
[Event "Computer Chess Game"]
[Site "HP"]
[Date "2016.02.07"]
[Round "-"]
[White "Fairy-Max 4.8S"]
[Black "SkipperWinb"]
[Result "1-0"]
[TimeControl "120"]
[Annotator "1. +0.09 1... -0.01"]
1. c4 {+0.09/8} Nc6 {-0.01/15 2.5} 2. Nf3 {+0.08/8 2.0} h6 {+0.02/15 2.4}
3. Nc3 {+0.10/8 1.5} Nf6 {+0.17/13 2.4} 4. d4 {+0.02/8 1.9} d6
{-0.07/13 2.3} 5. h4 {+0.04/8 3} Bf5 {-0.08/12 2.3} 6. Qb3 {+0.15/8 1.8} b6
{-0.20/12 2.3} 7. Bf4 {+0.15/8 2.3} Na5 {-0.10/12 2.2} 8. Qd1 {-0.26/8 6}
Qd7 {+0.00/12 2.1} 9. b4 {-0.18/8 1.9} Nc6 {-0.12/13 2.1} 10. Qa4
{-0.05/8 1.7} e5 {+0.05/12 2.1} 11. dxe5 {-0.01/8 2.1} dxe5 {-0.07/12 2.0}
12. Rd1 {+0.04/8 2.5} Qe6 {-0.18/12 2.0} 13. Nxe5 {+0.04/8 3} Bxb4
{-0.24/12 2.0} 14. Nxc6 {+0.13/8 1.9} Bxc3+ {-0.05/11 1.9} 15. Bd2
{+0.22/8 1.4} Bxd2+ {-0.30/11 1.8} 16. Rxd2 {-0.18/9 1.9} Qe4
{-0.20/11 1.8} 17. Nb8+ {+0.50/7 1.1} Ke7 {-0.30/9 2.0} 18. Rd3
{+0.60/8 1.6} Be6 {-0.27/10 1.9} 19. Nc6+ {+0.56/8 3} Kf8 {+0.07/11 1.7}
20. e3 {+0.11/8 1.3} Bxc4 {+0.10/11 1.7} 21. Rd4 {+1.10/10 1.9} Bxf1
{-0.46/12 2.0} 22. Rxe4 {+1.10/10 1.3} Bxg2 {-0.59/13 2.1} 23. Qb4+
{+1.67/10 2.2} Kg8 {+0.00/12 1.9} 24. Ne7+ {+1.65/10 1.3} Kf8
{+0.00/14 1.9} 25. Ng6+ {+2.35/9 0.9} Kg8 {+0.00/14 1.8} 26. Re5
{+2.31/10 1.3} Bxh1 {-0.51/12 1.8} 27. Nxh8 {+2.13/10 1.5} Kxh8
{-0.50/15 1.9} 28. Qc4 {+2.08/10 1.0} Kg8 {-0.50/13 1.7} 29. Qxc7
{+2.11/10 2.0} Bf3 {-0.58/12 1.7} 30. a4 {+2.25/9 1.0} a6 {-0.56/11 1.7}
31. Rf5 {+2.41/9 0.8} Be4 {-1.28/14 1.6} 32. Rf4 {+2.44/10 1.0} Rf8
{-1.33/15 1.5} 33. Qc4 {+2.61/10 1.9} b5 {-1.32/14 1.5} 34. axb5
{+2.94/12 1.1} axb5 {-1.37/14 1.5} 35. Qxb5 {+2.97/12 1.5} Rd8
{-1.56/13 1.4} 36. f3 {+3.01/10 1.4} Bd5 {-1.65/13 1.3} 37. Rd4
{+3.15/11 1.2} Rd7 {-1.67/15 1.3} 38. Qc5 {+3.18/11 1.2} Be6 {-1.64/15 1.4}
39. Qc8+ {+3.18/12 3} Kh7 {-1.49/15 1.3} 40. Rxd7 {+3.00/12 0.8} Nxd7
{-1.53/15 1.3} 41. Qc2+ {+3.00/11 0.8} Kg8 {-1.53/13 0.8} 42. f4
{+3.04/12 1.4} f5 {-1.38/14 0.8} 43. e4 {+3.12/13 0.7} fxe4 {-1.11/14 0.9}
44. Qxe4 {+3.12/13 0.9} Bg4 {-1.11/12 1.0} 45. Qd5+ {+3.39/11 1.3} Kf8
{-1.42/11 0.7} 46. f5 {+3.43/12 0.6} Nf6 {-1.31/11 0.7} 47. Qc5+
{+3.38/12 1.3} Kg8 {-1.37/14 0.7} 48. Qc4+ {+3.17/13 0.5} Kh7
{-1.37/15 0.7} 49. Qf4 {+2.99/14 0.8} Kg8 {-1.39/13 0.7} 50. Qf2
{+3.05/13 0.7} Kh7 {-1.33/14 0.7} 51. Qf1 {+3.01/12 0.6} h5 {-1.39/15 0.7}
52. Qd3 {+3.32/14 0.7} Kg8 {-1.39/13 0.7} 53. Qc4+ {+3.22/13 1.0} Kh8
{-1.38/13 0.8} 54. Qb5 {+3.24/12 0.5} Bf3 {-1.30/14 0.8} 55. Qb8+
{+3.14/12 0.7} Kh7 {-1.44/15 0.6} 56. Qg3 {+3.13/13 0.5} Bd5 {-1.39/13 0.6}
57. Qg6+ {+3.16/15 0.6} Kh8 {-1.40/16 0.6} 58. Qg1 {+3.06/12 0.7} Kg8
{-1.40/14 0.6} 59. Qh2 {+3.14/10 0.4} Kh7 {-1.40/12 0.6} 60. Qg3
{+3.03/13 0.6} Kg8 {-1.40/13 0.6} 61. Qb8+ {+3.14/12 0.8} Kf7
{-1.49/11 0.6} 62. Qa7+ {+3.25/11 0.4} Kg8 {-1.44/11 0.6} 63. Qe7
{+3.12/12 0.4} Kh7 {-1.49/13 0.5} 64. Qe3 {+3.09/11 0.4} Kh8 {-1.49/13 0.5}
65. Qc5 {+3.08/12 1.0} Kh7 {-1.49/14 0.6} 66. Qb5 {+2.96/13 0.9} Kg8
{-1.49/13 0.5} 67. Qe2 {+3.09/12 2.2} Kf7 {-1.49/12 0.6} 68. Qe5
{+3.16/9 0.3} Kg8 {-1.49/13 0.5} 69. Qd6 {+3.11/11 0.4} Kf7 {-1.49/12 0.5}
70. Qc7+ {+3.19/10 0.3} Kg8 {-1.49/13 0.5} 71. Qd8+ {+3.19/15 6} Kh7
{-1.49/13 0.5} 72. Qa5 {+3.04/15 3} Kh8 {-1.49/13 0.5} 73. Qd2
{+3.08/10 0.3} Kh7 {-1.49/14 0.5} 74. Qg5 {+3.01/12 0.2} Kg8 {-1.49/14 0.5}
75. Qf4 {+3.10/11 0.2} Kf7 {-1.49/11 0.5} 76. Qd4 {+3.22/9 0.3} Kg8
{-1.40/11 0.4} 77. Qd3 {+3.12/11 0.4} Kh7 {-1.49/12 0.4} 78. Qf1
{+3.06/9 0.3} Kg8 {-1.49/12 0.4} 79. Qb5 {+3.10/12 0.3} Kf7 {-1.41/11 0.4}
80. Qc5 {+3.17/11 0.2} Kg8 {-1.50/12 0.4} 81. Qc7 {+3.12/11 0.3} Kh7
{-1.49/13 0.4} 82. Qe7 {+3.07/11 0.3} Kg8 {-1.49/12 0.4} 83. Qe5
{+3.12/8 0.2} Kf7 {-1.49/12 0.4} 84. Qd6 {+3.11/9 0.4} Kg8 {-1.49/13 0.4}
85. Qb4 {+3.09/11 0.3} Kf7 {-1.50/11 0.4} 86. Qf4 {+3.10/10 0.2} Kg8
{-1.49/12 0.4} 87. Qd4 {+3.11/12 0.3} Kh7 {-1.49/13 0.4} 88. Qb4
{+3.06/11 0.4} Kh6 {-1.52/12 0.4} 89. Qc3 {+3.14/10 0.1} Kh7 {-1.50/13 0.4}
90. Qc2 {+3.05/11 0.1} Kg8 {-1.50/12 0.3} 91. Qc8+ {+3.12/11 0.2}
{Xboard: Forfeit due to invalid move: f6e4 (f6e4) res=23} 1-0
[/pgn]
Study your code until you understand it forward and backward. There should be NOTHING that "seems to work but I don't understand how / why".