Ok. To reiterate, it requires the squares being mapped to the bits in a bitboard such that the bits of a file are stored consecutively, not the more common orientation where the bits of a rank are consecutive.Gerd Isenberg wrote:Yes, please post it.
Then, you incrementally maintain, either in the search stack or your board structure, a byte[2][16] array which is a special pawn mask. The first index is the player, and the second index is the file, with some extras. It is necessary to have two extra files, one off of each edge of the board, so really only 10 files are necessary, but we use 16 so that the value can easily be popped into and out of the 128-bit XMM registers. You'll note, though, that except for the code for finding isolated pawns, nothing really needs the XMM registers for an 8x8 board because we're really only doing bit-wise operations of 64-bit groups. This array should be aligned to a 16-byte boundary for easy loading into XMM registers. For 8x8 board, I store the files for the actual board in bytes 4-12 so that it is quadword alligned. What is stored in this array is a mask which, for each player, has the bit set representing the back-most pawn, and all squares behind that pawn. For empty files, including the phantom files off the edges of the board, all bits are set.
Now that we have this information, to use it to find pawn information, you only need: the bitboard for the main board (bytes 4-12), the bitboard for the board shifted one file to the left (bytes 3-11), and the bitboard for the board shifted one file to the right (bytes 5-13.) You can do this by shifting the whole 128-bit mess in an XMM register, but it's just as easy to get them as follows (called center, left, and right, for simplicity)...
Code: Select all
byte behindPawns[2][16];
BitBoard64 center = *((BitBoard64 *) &behindPawns[0][4]);
BitBoard64 left = *((BitBoard64 *) &behindPawns[0][3]);
BitBoard64 right = *((BitBoard64 *) &behindPawns[0][5]);
Code: Select all
enemyPawns & center & left & right
Code: Select all
enemyKnights & left & right
Code: Select all
playerPawns & ((left & right) >> 1)
Doubled/tripled pawns:
Code: Select all
playerPawns & ~center
Code: Select all
playerPawns & left & right
Changing the bitboard square mapping may seem pretty radical, but, since all the pieces in chess have symmetric movements except the pawns, there is no practical difference between rank-major mapping and file-major mapping except where pawns are concerned. Finding pawn formations, however, is all about examining files, not ranks, so I respectfully submit that a mapping that stores the bits of the files consecutively is clearly superior. Additionally, if you use the XMM registers for all these operations, it works for boards of sizes up to 14x8 with little or no penalty!