Assuming the following values for each piece (from Chess 4.5 and others)
#define PAWN_VALUE 100
#define KNIGHT_VALUE 325
#define BISHOP_VALUE 350
#define ROOK_VALUE 500
#define QUEEN_VALUE 900
I created a 2D array indexed by attacker (down) and victim (across)
- Code: Select all
P N B R Q K
P - 6002 20225 20250 20400 20800 26900
N - 4775 6004 20025 20175 20575 26675
B - 4750 4975 6006 20150 20550 26650
R - 4600 4825 4850 6008 20400 26500
Q - 4200 4425 4450 4600 6010 26100
K - 3100 3325 3350 3500 3900 26000
King capture moves have the highest value (for non-legal move generation) so they sort to the top.
The values above 20000 are "good captures", 6000 range are equals, and anything lower is a bad capture.
The idea is to base the ordering on the difference between the values of the pieces, this comes to light esp. for knights and bishops. If you value a bishop higher than a knight, then NxB will be a good capture and BxN will not. the piece values are also used for the material calculation, so it follows that what is considered a good capture should be aligned with the evaluation. PXR scores the same as RxQ since the delta between their values is the same. As Bruce Moreland pointed out in his Programming Pages, MVV/LVA scores RxR ahead of PxB. That doesn't happen here. if you want ties to be broken, say to make RxQ sort higher than PxR, then just modify the value of the Queen to be 901, for example.
If your QSearch only does "good" captures and not "good/equal", then the selection only needs to look at moves with a score above 20000, otherwise, those above 6000. QxQ will be looked at before RxR.
This table is generated at compile time based on the values given to the pieces, so if they are tweaked, the table is automatically adjusted.
One can always tune the values by hand, but there are only a few places where it might matter.
comments/criticisms always welcome.