I've read various discussions on what base values should be used for the pieces and how one should deal with material imbalances. One approach is to make a huge table, indexed by piece counts from both sides and filling it up with appropriate values. That obviously lets you tune any sort of material imbalance you care to think about and it saves some special purpose code to detect material imbalances that change with, say, the number of pawns on the board.
At the same time, such a table is a bit opaque to me with respect to what's actually happening for any particular combination of material, and it doesn't seem like it's the sort of thing that should be necessary. I also don't have the resources to compile such a table for myself. In other words, I prefer to do something different.
I've seen people argue that rather than the more canonical 100/300/300/500/900 piece values, computer programs are better off using something like 100/400/400/600/1200. With these piece values, a minor for three pawns is calculated as a bad trade and it preserves exchange = two pawns and three minors = two rooks = one queen from the canonical values. That's useful, but at the same time, I don't really like the idea that much.
Enter the "bad trade" idea as implemented in Crafty. Superficially, this does more or less the same thing: by looking at the adjacent elements to the material balance, it effectively changes the value of a rook to 604 and the value of a minor to 413. Changing the base value of the pieces to those and recalculating would change the remaining elements of the table to be in the range 5-76 if we ignore the saturated elements far from the diagonal. So what it does is actually not very different from changing the piece values to the 100/400/400/600 scale. Nevertheless, I like this idea more because it seems a bit more clear what is going on.
So here's the question: I would like to use something similar in my own code, because I like the idea. However, there isn't much variation in how you could implement this (it's basically a 2-dimensional array indexed by number of minors and number of majors). At a stretch, it's possible to guess/calibrate the values in the table so they're different from the ones that are actually used in Crafty (which are probably not optimal for another program anyway), but that's about it as far as I can see.
To what extend is implementing this idea, inspired by Crafty, considered to be "copying"? Bearing in mind that any independent implementation is not going to be substantially different from the implementation in Crafty.
For reference, the relevant table in Crafty is this:
Code: Select all
/*
This array is indexed by rook advantage and minor piece advantage.
rook advantage is 4 + white rook equivalents - black rook equivalents
where a rook equivalent is number of rooks + 2 * number of queens.
minor piece advantage is 4 + white minors - black minors.
The classic bad trade case is two minors for a rook. If white trades
two minors for a rook, rook advantage is +5 and minor advantage is +2.
imbalance[5][2] gives a penalty of -42 for this trade.
*/
int imbalance[9][9] = {
/* n=-4 n=-3 n=-2 n=-1 n=0 n=+1 n=+2 n=+3 +n=+4 */
{-126, -126, -126, -126, -126, -126, -126, -126, -42 }, /* R=-4 */
{-126, -126, -126, -126, -126, -126, -126, -42, 42 }, /* R=-3 */
{-126, -126, -126, -126, -126, -126, -42, 42, 84 }, /* R=-2 */
{-126, -126, -126, -126, -104, -42, 42, 84, 126 }, /* R=-1 */
{-126, -126, -126, -88, 0, 88, 126, 126, 126 }, /* R=0 */
{-126, -84, -42, 42, 104, 126, 126, 126, 126 }, /* R=+1 */
{ -84, -42, 42, 126, 126, 126, 126, 126, 126 }, /* R=+2 */
{ -42, 42, 126, 126, 126, 126, 126, 126, 126 }, /* R=+3 */
{ 42, 126, 126, 126, 126, 126, 126, 126, 126 } /* R=+4 */
};