Computer Chess Club Archives


Search

Terms

Messages

Subject: sliding attacks in three #define

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.