static mobility(Q&D)
Posted: Wed Mar 13, 2013 7:19 am
The following should probably go under the header "quick and dirty kludges". (So just the sort of thing I like for micro-Max! )
The problem addressed is that calculating mobility in evaluation is quite expensive, while in search it is nearly available for free as a side effect of generating moves. Whenever you search a null move, you thus have available the mobility of both sides. This could be used to improve the evaluation in those nodes.
Unfortunately null moves are not done in QS, so you have this mobility term available only in ply-1 nodes, and their QS-daughters after null move. And in 1-ply nodes you don't really need an evaluation (you can't stand pat there), while even in the QS null-daughter you get it a bit late. (You can't stand pat before you have generated moves, but at least you can use the mobility-corrected eval for cutoff before searching them.)
But under the assumption that something is better than nothing, the daughters of the QS nodes could use the mobility eval term of their 1-ply or QS parents in their evaluation, rather than their (unavailable) own. This can be done by explicitly passing it with the Search call to QS, or, even simpler, by just adding it to the incrementally-updated material eval in the node where it was calculated. Having the entire QS tree using the same mobility term as its 1-ply root, is what I call 'static' mobility.
Now there are some things that obviously go awry in this scheme. Your, or your opponent's good mobility might depend on a piece that can be easily traded away, or is even hanging. It would be nice if the QS scores reflected that. But there is a poor-man's method to sort of incorporate that. In stead of updating the material eval as
You could add
where MST is a global 'mobility-square table' created in the 1-ply node when it calculated mobility in its move gen, storing the results per piece. So in fact you change the piece values with their mobilities, and make sure they take them along when they move in later moves. This makes 'semi-static' mobility, attached to the pieces rather than just the total evaluation. Of course you would have to restore the changes to the MST in UnMake().
In micro-Max, this scheme would be extra attractive, because QS after null move is forced to generate all moves before being allowed stand-pat anyway, because the null-move search is also used as check test (and cutoffs could make you miss a King capture, misjudging a mate as stalemate in the parent). So the semi-static mobility might not be 10% accurate, but is is almost completely free!
The problem addressed is that calculating mobility in evaluation is quite expensive, while in search it is nearly available for free as a side effect of generating moves. Whenever you search a null move, you thus have available the mobility of both sides. This could be used to improve the evaluation in those nodes.
Unfortunately null moves are not done in QS, so you have this mobility term available only in ply-1 nodes, and their QS-daughters after null move. And in 1-ply nodes you don't really need an evaluation (you can't stand pat there), while even in the QS null-daughter you get it a bit late. (You can't stand pat before you have generated moves, but at least you can use the mobility-corrected eval for cutoff before searching them.)
But under the assumption that something is better than nothing, the daughters of the QS nodes could use the mobility eval term of their 1-ply or QS parents in their evaluation, rather than their (unavailable) own. This can be done by explicitly passing it with the Search call to QS, or, even simpler, by just adding it to the incrementally-updated material eval in the node where it was calculated. Having the entire QS tree using the same mobility term as its 1-ply root, is what I call 'static' mobility.
Now there are some things that obviously go awry in this scheme. Your, or your opponent's good mobility might depend on a piece that can be easily traded away, or is even hanging. It would be nice if the QS scores reflected that. But there is a poor-man's method to sort of incorporate that. In stead of updating the material eval as
Code: Select all
material += PST[piece][to] - PST[piece][from] + PST[victim][to];
Code: Select all
material += PST[piece][to] - PST[piece][from] + PST[victim][to];
material += MST[to]; MST[to] = MST[from];
In micro-Max, this scheme would be extra attractive, because QS after null move is forced to generate all moves before being allowed stand-pat anyway, because the null-move search is also used as check test (and cutoffs could make you miss a King capture, misjudging a mate as stalemate in the parent). So the semi-static mobility might not be 10% accurate, but is is almost completely free!