strange: semi-valid moves give different game play
Moderator: Ras
-
flok
strange: semi-valid moves give different game play
Hi,
Something strange is happening.
I've adapted my program to generate semi-valid moves and only to check if it is valid when it will be used. The strange thing now is that this gives total different moves. Instead of eg e2e4 I get b1c3. That at itself is maybe not worrying but depths 1 upto 11 ttd of semi-valid is 10% faster than the valid-only version but depth 12 is 3x slower!
Now I don't understand this. The same list of moves is generated (validation at usage). Perft says all is fine (755 tests). Sorting should be the same.
Anyone got an idea what be this irregular behaviour? (the slow downs, and so on)
Something strange is happening.
I've adapted my program to generate semi-valid moves and only to check if it is valid when it will be used. The strange thing now is that this gives total different moves. Instead of eg e2e4 I get b1c3. That at itself is maybe not worrying but depths 1 upto 11 ttd of semi-valid is 10% faster than the valid-only version but depth 12 is 3x slower!
Now I don't understand this. The same list of moves is generated (validation at usage). Perft says all is fine (755 tests). Sorting should be the same.
Anyone got an idea what be this irregular behaviour? (the slow downs, and so on)
-
Robert Pope
- Posts: 570
- Joined: Sat Mar 25, 2006 8:27 pm
- Location: USA
- Full name: Robert Pope
Re: strange: semi-valid moves give different game play
Are the scores returned the same, or different?
-
flok
Re: strange: semi-valid moves give different game play
They must be the same: my eval consists of only:
- positional value
- object count and their values
(did some quick compares and they look the same)
- positional value
- object count and their values
(did some quick compares and they look the same)
-
Evert
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: strange: semi-valid moves give different game play
Are you absolutely certain that the legal moves are searched in the same order (ie, the only difference is in illegal moves that will be skipped)?
If they are, node counts should be exactly the same, so it should be fairly easy to find out where and why the search trees diverge.
If they are, node counts should be exactly the same, so it should be fairly easy to find out where and why the search trees diverge.
-
flok
Re: strange: semi-valid moves give different game play
I did notice that after ply 8 suddenly the pv is different.
valid only
semi valid
I think I remember that around depth 8 promotions come into play so I tried [d]1q6/P6k/8/5N1K/8/8/8/8 w - - 0 1
and valid:
semi-valid:
That is strange!
If I remove quiescence:
valid:
semi-valid:
move list
valid:
semi-valid:
the same!
Now one thing I just noticed that is different is this:
at the top of search() I check if nMoves (number of moves in the movelist) is 0. if so, then I call evaluate. I can't do that with semi-valid because then I would need to check each move and thus cancel the speed-win.
how can I work around that problem? I tried adding a check after the move-iteration to see if I did do any of them but then things like tt, iid and so on can influence the results.
valid only
Code: Select all
info depth 1 seldepth 2 score cp 12 time 1 nodes 21 pv b1c3
info depth 2 seldepth 4 score cp 0 time 2 nodes 81 pv b1c3 b8c6
info depth 3 seldepth 6 score cp 12 time 4 nodes 231 pv b1c3 b8c6 g1f3
info depth 4 seldepth 10 score cp 0 time 11 nodes 1846 pv b1c3 b8c6 g1f3 g8f6
info depth 5 seldepth 14 score cp 10 time 16 nodes 3625 pv b1c3 b8c6 g1f3 g8f6 d2d4
info depth 6 seldepth 16 score cp 0 time 30 nodes 8604 pv b1c3 b8c6 g1f3 g8f6 d2d4 d7d5
info depth 7 seldepth 22 score cp 5 time 71 nodes 24181 pv b1c3 b8c6 g1f3 g8f6 d2d4 d7d5 e2e3
info depth 8 seldepth 29 score cp 3 time 368 nodes 152883 pv e2e4 b8c6 b1c3 d7d6 d2d4 e7e5 d4d5 c6d4
info depth 9 seldepth 29 score cp 5 time 654 nodes 279486 pv e2e4 b8c6 b1c3 e7e5 f1c4 d8g5 d1f3 g8f6 g1e2
info depth 10 seldepth 32 score cp 3 time 938 nodes 409938 pv e2e4 b8c6 b1c3 e7e5 f1c4 d7d6 g1f3 g8f6 e1g1 c8g4
info depth 11 seldepth 37 score cp 5 time 1739 nodes 773577 pv e2e4 b8c6 b1c3 e7e5 g1f3 g8f6 d2d4 f8b4 f3e5 f6e4 d1f3 e4c3 b2c3 c6e5 d4e5
info depth 12 seldepth 37 score cp 5 time 3902 nodes 1746102 pv e2e4 b8c6 b1c3 e7e5 g1f3 g8f6 d2d4 f8b4 d4e5 f6e4 d1d3 e4c3 b2c3
Code: Select all
info depth 1 seldepth 2 score cp 12 time 1 nodes 21 pv b1c3
info depth 2 seldepth 4 score cp 0 time 1 nodes 81 pv b1c3 b8c6
info depth 3 seldepth 6 score cp 12 time 2 nodes 209 pv b1c3 b8c6 g1f3
info depth 4 seldepth 10 score cp 0 time 15 nodes 1731 pv b1c3 b8c6 g1f3 g8f6
info depth 5 seldepth 14 score cp 10 time 26 nodes 3446 pv b1c3 b8c6 g1f3 g8f6 d2d4
info depth 6 seldepth 16 score cp 0 time 41 nodes 7980 pv b1c3 b8c6 g1f3 g8f6 d2d4 d7d5
info depth 7 seldepth 22 score cp 5 time 72 nodes 20581 pv b1c3 b8c6 g1f3 g8f6 d2d4 d7d5 e2e3
info depth 8 seldepth 29 score cp 6 time 199 nodes 81626 pv d2d4 b8c6 d4d5 c6e5 f2f4 e5c4 b1d2 c4d6
info depth 9 seldepth 31 score cp 5 time 511 nodes 238806 pv b1c3 b8c6 g1f3 g8f6 d2d4 d7d5 e2e3 e7e6 f1d3
info depth 10 seldepth 34 score cp 5 time 762 nodes 375402 pv b1c3 b8c6 e2e4 g8f6 g1f3 d7d5 e4e5 f6e4 d2d4 e7e6 c3e4 d5e4
info depth 11 seldepth 36 score cp 5 time 1820 nodes 917035 pv b1c3 d7d5 g1f3 d5d4 c3b5 b8c6 e2e3 e7e5 e3d4 e5d4 d2d3
info depth 12 seldepth 40 score cp 7 time 6586 nodes 3381654 pv e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 g8f6 b1c3 c6d4 d1d4 d7d6
and valid:
Code: Select all
info depth 1 seldepth 2 score cp 639 time 1 nodes 18 pv a7b8=bCode: Select all
info depth 1 seldepth 2 score cp 1289 time 1 nodes 20 pv a7b8=qIf I remove quiescence:
valid:
Code: Select all
info depth 1 seldepth 0 score cp 639 time 1 nodes 1 pv a7b8=b
info depth 2 seldepth 0 score cp 637 time 1 nodes 19 pv a7b8=b h7g8Code: Select all
info depth 1 seldepth 0 score cp 1289 time 1 nodes 1 pv a7b8=q
info depth 2 seldepth 0 score cp 1289 time 1 nodes 21 pv a7b8=qvalid:
Code: Select all
a7xb8=q a7xb8=r a7xb8=b a7xb8=n a7-a8=q a7-a8=r a7-a8=b a7-a8=n f5-e3 f5-g3 f5-d4 f5-h4 f5-d6 f5-h6 f5-e7 f5-g7 h5-g4 h5-h4 h5-g5Code: Select all
a7xb8=q a7xb8=r a7xb8=b a7xb8=n a7-a8=q a7-a8=r a7-a8=b a7-a8=n f5-e3 f5-g3 f5-d4 f5-h4 f5-d6 f5-h6 f5-e7 f5-g7 h5-g4 h5-h4 h5-g5Now one thing I just noticed that is different is this:
at the top of search() I check if nMoves (number of moves in the movelist) is 0. if so, then I call evaluate. I can't do that with semi-valid because then I would need to check each move and thus cancel the speed-win.
how can I work around that problem? I tried adding a check after the move-iteration to see if I did do any of them but then things like tt, iid and so on can influence the results.
-
MahmoudUthman
- Posts: 237
- Joined: Sat Jan 17, 2015 11:54 pm
Re: strange: semi-valid moves give different game play
shouldn't you be returning mated in n score , instead of eval score since the position isn't quiet ?flok wrote:Now one thing I just noticed that is different is this:
at the top of search() I check if nMoves (number of moves in the movelist) is 0. if so, then I call evaluate. I can't do that with semi-valid because then I would need to check each move and thus cancel the speed-win.
how can I work around that problem? I tried adding a check after the move-iteration to see if I did do any of them but then things like tt, iid and so on can influence the results.
-
Evert
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: strange: semi-valid moves give different game play
You indeed check if any moves were tried after looping over the move list:flok wrote: Now one thing I just noticed that is different is this:
at the top of search() I check if nMoves (number of moves in the movelist) is 0. if so, then I call evaluate. I can't do that with semi-valid because then I would need to check each move and thus cancel the speed-win.
how can I work around that problem? I tried adding a check after the move-iteration to see if I did do any of them but then things like tt, iid and so on can influence the results.
Code: Select all
int legal_moves = moves_in_move_list;
for (all moves) {
if (move is illegal) {
legal_moves--;
next move
}
do search stuff.
}
if (legal_moves == 0) {
return appropriate value;
}
-
Evert
- Posts: 2929
- Joined: Sat Jan 22, 2011 12:42 am
- Location: NL
Re: strange: semi-valid moves give different game play
No need to look at move selection: node counts are different, and more importantly small enough that you can figure out what happens if you output the entire search tree.flok wrote: I think I remember that around depth 8 promotions come into play so I tried [d]1q6/P6k/8/5N1K/8/8/8/8 w - - 0 1
and valid:semi-valid:Code: Select all
info depth 1 seldepth 2 score cp 639 time 1 nodes 18 pv a7b8=bThat is strange!Code: Select all
info depth 1 seldepth 2 score cp 1289 time 1 nodes 20 pv a7b8=q
If I remove quiescence:
valid:semi-valid:Code: Select all
info depth 1 seldepth 0 score cp 639 time 1 nodes 1 pv a7b8=b info depth 2 seldepth 0 score cp 637 time 1 nodes 19 pv a7b8=b h7g8Code: Select all
info depth 1 seldepth 0 score cp 1289 time 1 nodes 1 pv a7b8=q info depth 2 seldepth 0 score cp 1289 time 1 nodes 21 pv a7b8=q
-
hgm
- Posts: 28461
- Joined: Fri Mar 10, 2006 10:06 am
- Location: Amsterdam
- Full name: H G Muller
Re: strange: semi-valid moves give different game play
It means something is buggy for sure. If you just moved legality testing of the move from the move generator to MakeMove, but generate moves in the same order, you should get the same tree, up to the same node count. Only when you moved the legality test to the daughter node, and count it as a node before passing the test, the counts could be different. But the tree should stay the same.flok wrote:Anyone got an idea what be this irregular behaviour? (the slow downs, and so on)
Easy to debug, however: in each node, print the path to the node on a file. Do that for both versions. Then compare the file to see where the first difference occurs.
Possible causes of differences: acceptance of illegal hash moves (after key collision) or killer moves,which are now caught during MakeMove.
-
flok
Re: strange: semi-valid moves give different game play
Found it or at least something: it's the stale mate detection what makes it different.
At the top of search() I check for stale mate. If so, then I return 0. Else I'll continue with eg the check if nMoves == 0 and then I do an evaluate.
Now due to the semi-valid movelist, stale mate does not trigger. I can move that to just after the move-iteration but then the depthLeft == 0 (triggering evaluate/qs) is triggered first.
At the top of search() I check for stale mate. If so, then I return 0. Else I'll continue with eg the check if nMoves == 0 and then I do an evaluate.
Now due to the semi-valid movelist, stale mate does not trigger. I can move that to just after the move-iteration but then the depthLeft == 0 (triggering evaluate/qs) is triggered first.