Author: rasjid chan
Date: 11:16:42 04/09/04
Go up one level in this thread
On April 09, 2004 at 13:03:26, Vincent Diepeveen wrote: >On April 09, 2004 at 12:01:20, rasjid chan wrote: > >I completely agree with Christophe. > >Faster than bitboards for complex software is using my publicly posted as Gerd >says "straightforward code" to generate moves. > >Without inline assembly at opteron bitboards is just dead slow. > >Who wants to program in assembly in the year 2004? I have great respect for the knowledge and insight of Christophe in chess programming which he probably gain thru much hardwork. I remember reading a first post by him about ... most people think chess programming is about evaluation. It is not... it is about search... " I almost fully agree with his observation and this is what my direction is. About this bitboard stuff that I posted, I think a mistake. Also I used the wrong words ... fast complete sliding attacks... and he has done a lot examining the various board representations and their efficiency. My "fast" is actually about new programmers who just want to have sliding attacks which can easily be stuff into their programs for testing and they MAY NOT be fast in CPU execution. I still sometimes have to use sliding attacks for exceptional cases so those three #define are handy (fast), ONLY THREE LINES; they are NOT in my move generator. Christophe is talking about REAL FAST CODES. I never test the speed of my codes (NOT YET) - but I know the other way of 0x88 is using step[128 + to - from] and I simply dislike an array of char step[256] as again at one time warnings are everywhere about memory bottle-necks. So using non-bitboard may require me to have memory swap whereas my #define , at least for the rooks, are all "within CPU". But I don't know if it is faster. Thanks for your reply Rasjid > >>On April 09, 2004 at 10:59:45, Christophe Theron wrote: >> >>>On April 09, 2004 at 02:30:36, rasjid chan wrote: >>> >>>> >>>> >>>>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; >>>> } >>>> } >>> >>> >>> >>> >>>Clearly, nothing beats the ugliness of bitboards. >>> >>> >>> >>> Christophe >> >>...implement fast complete attacks...
This page took 0 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.