For my engines IID has always proved useful in any node (even all-nodes, because you can never be sure they are all-nodes). But that was of course with an efficient implementation, not with a crappy recursive call to redo the same node, so that it does a lot of work in duplicate, and then throws all of it away except for the hash move.
Well, I did not test that specifically, but why not? Checks are often given to delay losses. I could have a pin, fork or skewer that I can cash on to get above beta, but I have to resolve the check first, in a correct way. The check will hardly have lowerd the opponent's score, so if we are below alpha after it, the opponent would have been above beta before it. And yet he stooped to searching checks, rather than comfortably leaning back with a null move. So apparently he is under threat, and likely many non-checks he tried first already failed low. Normal move ordering (killers, history) usually doesn't work well when in check, so the chances I will find the proper refutation by static means is not very large, if the check wasn't a pointless sacrifice. Searching checks is expensive, because they get exteded, so even if they occur rarely in the tree, treating them efficiently might have a measurable impact.
hgm wrote:For my engines IID has always proved useful in any node (even all-nodes, because you can never be sure they are all-nodes). But that was of course with an efficient implementation, not with a crappy recursive call to redo the same node, so that it does a lot of work in duplicate, and then throws all of it away except for the hash move.
Could you please elaborate on the non-crappy way? Thanks.
Just loop over depth after move generation, so that you can continue to use the same move list, and benefit from any sorting that has been applied to it at lower depth. My search routines typically looks like this: