Author: rasjid chan
Date: 23:30:36 04/08/04
I have a set of simple macros for bitboard operations and they are meant for those with a new chess program and like to implement fast complete attacks by bishops and rooks. It is basically just three #define and all sliding attacks would then be available for use in evaluations and move ordering. Of course it is only when we don't yet count instruction cycles, but then after things are moving we could EASILY upgrade to rotated bitboards. The only requirement is that the "all" bits must be available. Most chess programmers sooner or later will have to use some bitboard operations as there seem no escape for the sliding pieces and it is usually necessary to incrementally update the "all" bits after makemove()and unmake(). These bitboard operations just make use of simple direct intuitive operations.If we have a single bit x, then x - 1 divides the board into upper half and lower half and add to it some bitwise operations which everyone say is fast. The only memory access is U64 diagonal[2][15] and it is much better than U64 attack[64][64]. For those not using 0x88, they just need some simple editing. If anyone has something faster or can make them faster, please post. Best Regards Rasjid typedef unsigned _int64 U64 #define GetFile64(sq) ((sq) & 7) #define GetRank64(sq) ((sq) >> 3) #define iGetFile(sq88) ((sq88) & 7) #define iGetRank(sq88) ((sq88) >> 4) #define sq88Bit(sq88) ((U64)1 << (((sq88) + ((sq88) & 7)) >> 1)) #define sq64Bit(sq64) (((U64)1) << (sq64)) #define sq88RankBits(sq88) ((U64)0xff << ((sq88) >> 1 & 0370)) #define sq88FileBits(sq88) ((U64) 0x0101010101010101 << ((sq88) & 7)) //*** global variables U64 all, diagonal[2][15]; //*** Start - bitboard attack operations for sliding pieces /* This test that the in-between arc (x, y) is clear of any bits. path is the complete bit path along x, y across the board */ #define brq_path_clear(x, y, path) ((x) <= (y) ? ((x) == (y) || isqBit(y) - 1 & ~(isqBit(x) - 1 | isqBit(x)) & (path) & all ? 0 : 1) : (isqBit(x) - 1 & ~(isqBit(y) - 1 | isqBit(y)) & (path) & all ? 0 : 1)) /* given any two sq88 x, y , this test if they attack along diagonals. */ #define bstyle_attack(x, y) (iGetRank(x) + iGetFile(x) == iGetRank(y) + iGetFile(y) ? (brq_path_clear(x, y, diagonal[1][iGetRank(x) + iGetFile(x)]) ? 1 : 0) : (iGetRank(x) - iGetFile(x) == iGetRank(y) - iGetFile(y) ? (brq_path_clear(x, y, diagonal[0][7 + iGetRank(x) - iGetFile(x)]) ? 1 : 0) : 0)) /* given any two sq88 x, y , this test if they attack along rank or file. */ #define rstyle_attack(x, y) (iGetRank(x) == iGetRank(y) ? (brq_path_clear(x, y, isqRankBits(x)) ? 1 : 0) : (iGetFile(x) == iGetFile(y) ? (brq_path_clear(x, y, isqFileBits(x)) ? 1 : 0) : 0)) //*** End - bitboard attack operations for sliding pieces void pre_calculate_diagonal(){ int i, j, l; //get diagonal[2][15] memset(diagonal, 0, sizeof(diagonal)); //LR down == [0][7 + r - f] //RL down == [1][r + f] i = 0; while(!(i & 0x88)){ l = iGetRank(i) - iGetFile(i); assert(7 + l >= 0 && 7 + l < 15); for (j = i; !(j & 0x88); j += 17){ diagonal[0][7 + iGetRank(j) - iGetFile(j)] |= isqBit(j); assert(l == iGetRank(j) - iGetFile(j)); } l = iGetRank(i) + iGetFile(i); assert(l >= 0 && l < 15); for (j = i; !(j & 0x88); j += 15){ diagonal[1][iGetRank(j) + iGetFile(j)] |= isqBit(j); assert(l == iGetRank(j) + iGetFile(j)); } ++i; } i = 16; while(!(i & 0x88)){ l = iGetRank(i) - iGetFile(i); assert(7 + l >= 0 && 7 + l < 15); for (j = i; !(j & 0x88); j += 17){ diagonal[0][7 + iGetRank(j) - iGetFile(j)] |= isqBit(j); assert(l == iGetRank(j) - iGetFile(j)); } i += 16; } i = 23; while(!(i & 0x88)){ l = iGetRank(i) + iGetFile(i); assert(l >= 0 && l < 15); for (j = i; !(j & 0x88); j += 15){ diagonal[1][iGetRank(j) + iGetFile(j)] |= isqBit(j); assert(l == iGetRank(j) + iGetFile(j)); } i += 16; } }
This page took 0.06 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.