Quiescence search implementation (Beginner)

Discussion of chess software programming and technical issues.

Moderator: Ras

verminox

Quiescence search implementation (Beginner)

Post by verminox »

In the early version of my engine, all i did at leaf nodes that are not quiet was something like SEE. I just recursively found the least valuable attacker on the move square and got the result of the exchange. However, I realised many flaws with this method. For example, exchanges need not necessarily be on the same square, and checks/promotions can't be extended in this way.

I've read a lot about quiescence search and realised it's importance but I don't really get why it has to be a whole new routine (function). Both the CPWiki and Wikipedia show quiescence search as a completely different routine, just as it were a whole new component of the search.

From what I understand, quiescence searching just means "at a leaf node, if the last move was not quiet, then search further". From this, I deduced the following logic:

Code: Select all

search(alpha, beta, depth)
{
  if( depth == 0 )
  {
    if( is_quiet(last_move) )
      return static_eval();
    else
      depth  = 1;
  }
  foreach ( move in legal_moves )
  {
    /* standard alpha-beta, perform the move and search to (depth-1) */
  }
}
In this way, all violent leaf nodes will get searched one ply deeper. If the node at the next ply was quiet, the score is returned from the general AB-search or else that particular node is extended even further.

Is there much else to quiescence search? Are there things to do in the quiescence search that you would not do in a normal alpha-beta search? What is wrong with my logic?
Teemu Pudas
Posts: 88
Joined: Wed Mar 25, 2009 12:49 pm

Re: Quiescence search implementation (Beginner)

Post by Teemu Pudas »

From what I understand, quiescence searching just means "at a leaf node, if the last move was not quiet, then search further".
No.

If eval >= beta, return eval.
Else search non-quiet moves and return max(search_score, eval)
mainsworthy2

Re: Quiescence search implementation (Beginner)

Post by mainsworthy2 »

http://web.archive.org/web/200404270144 ... escent.htm

I found out all I needed from above link :)
User avatar
hgm
Posts: 28461
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Quiescence search implementation (Beginner)

Post by hgm »

If a position is quiet or not does not depend on the move leading to it, but on the moves you can do from it.

In QS you first do the evaluation assuming the node is quiet. If that is not good enough to fail high, your only hope left is then tht it is not quiet, and that you have a capture that wins material. So you start searching as usual, except that you consider only captures. (i.e. you search the captures as if d=1, and ignore the non-captures.)

If you want to keep it simple, you can very easily use the same routine in QS as in the full-width search. Just, in stead of starting the best score at -infinity, you start it at the current eval. And then, in the loop over moves, skip all non-captres.

To prevent search explosion, it is important that you capture the most-valuable piece first.
verminox

Re: Quiescence search implementation (Beginner)

Post by verminox »

That article did clear a few doubts about the difference between alpha-beta and quiescence search. Thanks.
verminox

Re: Quiescence search implementation (Beginner)

Post by verminox »

hgm wrote:If a position is quiet or not does not depend on the move leading to it, but on the moves you can do from it.
Ahh, ok I see I had a misconception there. But, in the middlegame you might reach a position where there can be a long sequence of 6-8 captures... now won't that explode the search tree?
hgm wrote:To prevent search explosion, it is important that you capture the most-valuable piece first.
But, as written in Morland's article, won't this suffer from the fact that RxR is considered more valuable than PxB even if the rook was defended? Using SEE for move ordering seems scary to me (I imagine that would seriously slow down the move ordering)... Do most engines use SEE or MVV in move ordering captures?
frankp
Posts: 233
Joined: Sun Mar 12, 2006 3:11 pm

Re: Quiescence search implementation (Beginner)

Post by frankp »

R x Q wins at least (Q - R).
Q x R may win (R) or loose (Q - R) if the Q can be captured by the opponent.
You only need to do SEE on captures that may lose material i.e. the second case of the above.

(The second case is of course simplified. You could have a longer sequence:
Q x R, Q x Q, N x Q and you win a whole rook, for example. SEE will reveal this too.)
User avatar
hgm
Posts: 28461
Joined: Fri Mar 10, 2006 10:06 am
Location: Amsterdam
Full name: H G Muller

Re: Quiescence search implementation (Beginner)

Post by hgm »

Search explosion occurs because Queens of both sides start out on 'plunder raids', grazing the board empty through unsound captures. Before you know it, you are 20 ply deep in QS alone. Later, of course, it will turn out that this line is totally irrelevant, because the very early moves are easily refuted. But then you have already spent a million nodes or so to figure out in how many ways the Queens can gobble up the various pieces on the board (in different order).

If you put a stop to such plunder raids at the earliest possible moment, by taking a Queen as soon as you can, this problem can't occur.

The other disccussions are merely about how to reduce te average size od a QS tree from 10 nodes to 7. Not from 1,000,000 to 10.
User avatar
Don
Posts: 5106
Joined: Tue Apr 29, 2008 4:27 pm

Re: Quiescence search implementation (Beginner)

Post by Don »

verminox wrote:In the early version of my engine, all i did at leaf nodes that are not quiet was something like SEE. I just recursively found the least valuable attacker on the move square and got the result of the exchange. However, I realised many flaws with this method. For example, exchanges need not necessarily be on the same square, and checks/promotions can't be extended in this way.

I've read a lot about quiescence search and realised it's importance but I don't really get why it has to be a whole new routine (function). Both the CPWiki and Wikipedia show quiescence search as a completely different routine, just as it were a whole new component of the search.

From what I understand, quiescence searching just means "at a leaf node, if the last move was not quiet, then search further". From this, I deduced the following logic:

Code: Select all

search(alpha, beta, depth)
{
  if( depth == 0 )
  {
    if( is_quiet(last_move) )
      return static_eval();
    else
      depth  = 1;
  }
  foreach ( move in legal_moves )
  {
    /* standard alpha-beta, perform the move and search to (depth-1) */
  }
}
In this way, all violent leaf nodes will get searched one ply deeper. If the node at the next ply was quiet, the score is returned from the general AB-search or else that particular node is extended even further.

Is there much else to quiescence search? Are there things to do in the quiescence search that you would not do in a normal alpha-beta search? What is wrong with my logic?
It's mainly just semantics. The classic quiescence search is a search than contains only captures and each side can consider a non-move as option. This of it as just another move, except that you evaluate the position and stop searching when you choose that option. Sometimes this is called "standing pat."

Example: I do a 7 ply search and now I'm in quies. On the 8th ply, I have 3 captures, QxP, RxN and NxP. I have 4 options here, play one of the 3 capture moves, or stop searching (after calling the evaluator.)

The search chooses which is best, doing nothing, or making one of those captures. Each possibility is explored (but the doing nothing option is explored only by calling the static evaluation function.)

Since there is a good chance all 3 captures are blunders, the search might choose to score the position and stop searching. But of course one of those captures may be advantageous too, but the search will figure that out for you.

The assumption of such a "stand pat" search is that if it's your turn to move, you can do no worse than scoring the position as is, but you might very well do better by trying a capture. That assumption is not always true of course, but you have to stop searching somewhere.

That is the short version. In practice, some program explore other moves, such as non-capture checks and so on. If a capture puts a king in check, you might choose to look at out of check moves (but some program don't bother to do this in order to save time.) If you ignore checks, you can simply apply the same stand pat logic and try just captures or stop. Just because you are in check doesn't mean you lose, most of the time you have a safe response.
verminox

Re: Quiescence search implementation (Beginner)

Post by verminox »

hgm wrote:If you put a stop to such plunder raids at the earliest possible moment, by taking a Queen as soon as you can, this problem can't occur..
So basically, the best way to avoid unsound deep capture sequences is to have a good move ordering, because the queen plunder raids will soon cause a cut-off? Am I getting this right?