H. G. Muller wrote on Mon, Sep 9, 2019 08:38 AM UTC:
I had similar problems in Shogi, when I tried to search check drops in addition to captures. Some lines just continue forever, and with depth-first that is of course fatal. This looks especially stupid when alternative moves to the infinite line in many places include a mate-in-1, which would have alpha-beta pruned the infinite line had they been searched first. So I tried a scheme with an iteratively deepened QS that would back up score intervals rather than one-sided score bounds (and would return {standPat, INF} for QS nodes with captures that were too deep to search), deepening it until the interval in the QS root collapsed to a single value. This way you would find the closest forcible (through QS moves) mate before searching any deeper lines. But this still wasn't enough to make the problem disappear, so I abandoned that again, and only search captures now.
The problem is that this is really very wrong in games with piece drops. Even recapture exchanges are often meaningless there, as the capture of a protected piece might give the opponent the piece in hand that he needs for an all-check-drops mate, so that you cannot afford to recapture. It seems Bonanza in every QS node first does a 3-ply checks-only search to see if it can checkmate that way, and if it cannot searches only captures (or stand-pat).
Even most engines for orthodox chess limit the search of checks to the first two ply of QS. They are furthermore selective in what checks they search, and usually prune those that can be evaded by a SEE > 0 capture on the checking piece.
It is still an open question for me how, when you have a QS that also is controlled by a depth parameter, you can best increase the tree size in an iterative deepening scheme. The simplest way would be to just keep the QS depth fixed, and iterate the depth of the full-width search as usual. I suspect this is very sub-optimal, though, as it requires the tactics that QS misses because of the depth limitation to be discovered by the full-width part. Which is not only the most expensive thing you could do in the leading plies from the position that was too complex, but adds to the tree everywhere. It leads to the complex tactics being resolved only when the branches ending in simple tactics (presumably the large majority) have already been deepened too, while the resolved score could be such that it upsets the entire tree, making most of the deepened lines irrelevant.
Increasing the depth of individual QS until they converge OTOH leads to very much (possibly infinite) effort on QS that in the end might turn out to have scores that makes the branch leading to them irrelevant. Iteratively increasing the QS depth limit in the tree as a whole before increasing the depth of the full-width search would waste a lot of time walking the same full-width tree in parts where you encounter only QS that have already converged for the current depth limit.
I have the feeling it should be possible to control the search depth with a single parameter from the root, which would both increase the QS depth limit and the full-width depth as it grows. E.g. with a QS that does an M-ply all-capture search followed by unlimited-depth recapture-only, you could keep track of whether the QS actually did prune any captures that were not recaptures. If there were, M was not large enough to converge the QS, and would have to be increased. The search could be made to converge the QS first, before being allowed to search any non-captures. E.g. by counting each QS ply as half a full-width ply, and when an N-ply search is requested, start with a QS there, increasing the QS depth limit to at most 2N. If QS converges before that, it all moves with a d=N-1 reply (or applicably further reduced), if not, it just returns the unconverged QS result (signalling to the parent that it cannot yet switch to full-width).
I had similar problems in Shogi, when I tried to search check drops in addition to captures. Some lines just continue forever, and with depth-first that is of course fatal. This looks especially stupid when alternative moves to the infinite line in many places include a mate-in-1, which would have alpha-beta pruned the infinite line had they been searched first. So I tried a scheme with an iteratively deepened QS that would back up score intervals rather than one-sided score bounds (and would return {standPat, INF} for QS nodes with captures that were too deep to search), deepening it until the interval in the QS root collapsed to a single value. This way you would find the closest forcible (through QS moves) mate before searching any deeper lines. But this still wasn't enough to make the problem disappear, so I abandoned that again, and only search captures now.
The problem is that this is really very wrong in games with piece drops. Even recapture exchanges are often meaningless there, as the capture of a protected piece might give the opponent the piece in hand that he needs for an all-check-drops mate, so that you cannot afford to recapture. It seems Bonanza in every QS node first does a 3-ply checks-only search to see if it can checkmate that way, and if it cannot searches only captures (or stand-pat).
Even most engines for orthodox chess limit the search of checks to the first two ply of QS. They are furthermore selective in what checks they search, and usually prune those that can be evaded by a SEE > 0 capture on the checking piece.
It is still an open question for me how, when you have a QS that also is controlled by a depth parameter, you can best increase the tree size in an iterative deepening scheme. The simplest way would be to just keep the QS depth fixed, and iterate the depth of the full-width search as usual. I suspect this is very sub-optimal, though, as it requires the tactics that QS misses because of the depth limitation to be discovered by the full-width part. Which is not only the most expensive thing you could do in the leading plies from the position that was too complex, but adds to the tree everywhere. It leads to the complex tactics being resolved only when the branches ending in simple tactics (presumably the large majority) have already been deepened too, while the resolved score could be such that it upsets the entire tree, making most of the deepened lines irrelevant.
Increasing the depth of individual QS until they converge OTOH leads to very much (possibly infinite) effort on QS that in the end might turn out to have scores that makes the branch leading to them irrelevant. Iteratively increasing the QS depth limit in the tree as a whole before increasing the depth of the full-width search would waste a lot of time walking the same full-width tree in parts where you encounter only QS that have already converged for the current depth limit.
I have the feeling it should be possible to control the search depth with a single parameter from the root, which would both increase the QS depth limit and the full-width depth as it grows. E.g. with a QS that does an M-ply all-capture search followed by unlimited-depth recapture-only, you could keep track of whether the QS actually did prune any captures that were not recaptures. If there were, M was not large enough to converge the QS, and would have to be increased. The search could be made to converge the QS first, before being allowed to search any non-captures. E.g. by counting each QS ply as half a full-width ply, and when an N-ply search is requested, start with a QS there, increasing the QS depth limit to at most 2N. If QS converges before that, it all moves with a d=N-1 reply (or applicably further reduced), if not, it just returns the unconverged QS result (signalling to the parent that it cannot yet switch to full-width).