hgm wrote:You are correct: It did not occur to me to update the explanation of variable names yet. I did not change many names, but the assignments of R and W in the old explanation were tentative, i.e. I had them reserved for making future changes that in the end did not prove (sufficiently) benificial.
R is now the game-stage indicator, starting at 0, and reaching 40 when all non-Pawn material is captured. So (R>>2) is a Pawn push bonus that increases from 0 to 10 as the game progresses. (By the way, using this term was suggested to me by Maarten Claessens.)
x-2&M tests if the square 2 left from the FROM square x is on the board (it is non-zero, i.e. true, if it is off the board).
If it is on the board, the || operator needs to evaluate its right-hand-side operand, b[x-2]-u, which is then an on-board access that compares the piece at square x-2 with the piece that moved, u. If they are the same (i.e. both Pawns, as this happens in the section that is only executed for Pawn moves, and of the same color) the expression (x-2&M||b[x-2]-u), which is parsed as ((x-2)&M) || (b[x-2]-u), evaluates to 0 (meaning no penalty), if there isn't an own pawn there, or it was off board, it evaluates to 1 (which is later multiplied by the factor 9 in front of the parantheses), and you get the penalty.
The last two lines are the 6th/7th rank bonus, which is indeed the most obfuscated part of the code:
y is the TO square, y+16 shifts it one rank, (to number ranks from 1-8, rather than 0 to 7) and (y+16)&32 then isolates the '2' bit of the binary rank number. Thus it evaluates to 32 for a TO square on rank 2,3,6 and 7, and to zero otherwise. Then it is ANDed with u, which in the '32' bit encodes if the Pawn moving now had moved before ('virgin bit'). If it had not, than the Pawn was apparently on the 2nd rank, and the current TO square thus on the 3rd rank, and the '32' bit ends up cleared. So the value of 32 only results for Pawns pushed to 6th/7th rank (if they are white; 2nd/3rd if they are black). Multiplying by 2 gives the mentioned bonus of 64.
Now y+r+1 is where you get if you would continue the current move by one more step (r) and one square to the right, and with &S (S=128) you test if this falls off the board rank-wise. If it does, the current Pawn move was a promotion, and it gets the bonus 647-p, (as specified by the conditional (y+r+1) ? ... : ... operator), where p is the piece type: 1 or 2 depending on the color of the Pawn.
So in the end V is set to 647-p (promotion), 64 (move to 6th/7th rank) or 0 (other Pawn moves).
This V is than added to i, (V+=i), which holds value of captured material, to incorporate the calculated bonus in the score of the move. In total a promotion earns 64+64+647-p = 775-p = 773 or 774, (as you always have to cross 6th and 7th rank to promote), which is approximately the difference in value of Queen and Pawn.
This V is also added to the piece code on the board b[y], so that it is increased by 64 for Pawns on the 6th, 128 for pawns on the 7th, and 775-p for 'Pawns' on the 8th. As the piece type originally was p, this means that for a Pawn on the 8th the piece type becomes 775 = 768+7. But as the board is an array of char, the 768 = 3*256 is clipped off, and only the 7 remains, which happens to be the piece type for a Queen.
For Pawns on 6th or 7th the bonus of 64 or 128 remains stored in their piece encoding on the board (in bits that were otherwise unused), so that it can be added to the piece value when the Pawn should be captured on 6th or 7th rank. In effect this makes Pawns on 6th or 7th rank distinct pieces, different from ordinary Pawns, with different piece values, (but with the same moves), to which ordinary Pawns promote if they reach 6th or 7th rank.
I like this description. It almost seems like taking advantage of mathematical coincidenties.
I was wondering, is it an idea to give a capturing piece the bonusses of the piece it captures ? It would avoid the "put the piece on the best square before I loose it". It would introduce some other bad beheavior, but I can't theorise which would be worse. Might be an idea to try.
Cheers,
Tony