SEE: what you see and what you get?
Posted: 26 Jan 2006, 12:57
I am curious how one generally handles the trade off between speed and accuracy of Static Exchange Evaluation, for which purposes the SEE value is used (e.g. move sorting, pruning/reduction/extension decisions), and how clever the SEE has to be to be suitable for a certain application. There are so many publicly available sources nowadays, that I don't know where best to look for a representative example.
In my old engine from 1983 I was using an extremely simplistic SEE: the program maintained a table counting the number of (capture) moves to each square of the board for each side separately (also counting pseudo-captures, i.e. captures of your own pieces), as well as the value of the lightest piece that covered that square. If for a certain square the number of attackers was larger than the number of defenders SEE returned a loss of the piece on that square or the lightest defender (whichever was smaller). If the number of defenders was larger or equal, it returned 0 or the value difference between the piece and its lightest attacker, whichever was larger.
Despite its coarse nature, this was enough to cover the most common cases. (Most common mistakes occur when a piece is defended by very heavy pieces only, like K+Q.) It probably would have been good enough for move sorting, where it does not hurt you very bad if you now and then make a gross mistake, as long as it does not happen too often. But unfortunately I used it as part of the evaluation in leaf nodes, and it was not nearly good enough for that. So the program played like cr*p, even worse then when I would not include this term in the evaluation at all for the same search depth...
How far can you go making a smart SEE without making the algorithm as expensive as a (quiescence-like) search? Are there smart algorithms around for this? I would be very happy with a SEE that would recognize pinnings (also on other pieces than the King!), (de)blocking threats (such as doubled Rooks, but also things like a Bishop stepping away from a Rook line) and overloaded defenders.
In my old engine from 1983 I was using an extremely simplistic SEE: the program maintained a table counting the number of (capture) moves to each square of the board for each side separately (also counting pseudo-captures, i.e. captures of your own pieces), as well as the value of the lightest piece that covered that square. If for a certain square the number of attackers was larger than the number of defenders SEE returned a loss of the piece on that square or the lightest defender (whichever was smaller). If the number of defenders was larger or equal, it returned 0 or the value difference between the piece and its lightest attacker, whichever was larger.
Despite its coarse nature, this was enough to cover the most common cases. (Most common mistakes occur when a piece is defended by very heavy pieces only, like K+Q.) It probably would have been good enough for move sorting, where it does not hurt you very bad if you now and then make a gross mistake, as long as it does not happen too often. But unfortunately I used it as part of the evaluation in leaf nodes, and it was not nearly good enough for that. So the program played like cr*p, even worse then when I would not include this term in the evaluation at all for the same search depth...
How far can you go making a smart SEE without making the algorithm as expensive as a (quiescence-like) search? Are there smart algorithms around for this? I would be very happy with a SEE that would recognize pinnings (also on other pieces than the King!), (de)blocking threats (such as doubled Rooks, but also things like a Bishop stepping away from a Rook line) and overloaded defenders.