I have difficulties to see why this explanation makes quiescence search easier to understand. Why do you introduce the "null" move here and mix it with the qsearch? Is it a way of expressing the "stand pat" principle?Don wrote:You should do quies search next. Nothing else you can do makes any sense until you do this. It's easy, here is a way that you won't have to think too hard about:
1. create a new move call null, which does nothing to the board. It's a real move, so when white plays the null or "nothing" move, it's blacks turn to move. It should work like any other move except nothing is actually moved on the board.
2. In quies, always try the null move first, then try only captures.
3. If you want to deal with checks, try all the moves when in check.
Some program, even strong ones don't worry about checks and out of checks, just let the program capture the king but give it a super high score.
The pay-off for a quies search is huge, it's the next thing you want to have.
I wanted to make this simple, but if you don't actaully have to "make" the null move (it does nothing anyway.) Just pretend you are making it. Toggle the side to move, score the position, check to see if it's a beta cutoff, update alpha (and the best score), etc. Do everything you would do if you were actually making a real move. That is your quies search.
I'd propose not to follow that path with the "null" move for implementing quiescence search. QS can be simply explained like this:
- If the maximum search depth (horizon) is reached within the full width search and the moving side is not in check then the value of the current position is determined by a quiescence search (QS).
- Within QS, the value from the viewpoint of the moving side is at least the static evaluation of the current node, because we assume for simplicity that the moving side is not forced to capture anything.
- If there is a capture sequence which the moving side can enforce and which leads to a value better than the static evaluation then this is the QS value. So at each QS node, the moving side "decides" whether to start (or continue) a capture sequence or stick with the current static evaluation. Therefore evaluate() is always called first, then all captures are generated and tried in a "good" order.
- Move ordering within QS is important since this is by far the largest part of the whole search tree (often 80-90% of all nodes). Use the simple MVV/LVA.
- QS follows the normal rules of alpha-beta search.
I think that's it, and together with the Bruce Moreland page you should be able to implement this tiny piece of code. Generating only captures could, as a first but inefficient step, be simulated by generating all moves but selecting only captures for the search while discarding all others. Many efficiency improvements are possible in QS but can initially be skipped until later.
Sven
