Author: Alessandro Damiani
Date: 10:26:15 10/22/00
Go up one level in this thread
On October 22, 2000 at 11:26:58, Severi Salminen wrote: >Hi! > >I have started again from scratch to program a chess engine, now with C. I came >to this solution to generate rook moves without rotated bitboards: > >I wont show you everything :) but here is some code from my mov_gen routine. E >holds all the pieces on board, j is the position of our Rook (0=H1 and 63=A8). F >is an empty bitboard and D holds the horizontal squares which we can move to >(calculated before this) > > >// Aligning the file info to right corner of bitboard and clearing all other >// bits: > E=(E>>(j&7))&0x0101010101010101; > > for(k=0, F=0;k<8;k++) > { > F|=E; > E>>=7; > } > F&=0xff; > >//After the loop F holds the file info and we can fetch the squares from >//a pre-compiled table and OR them with the horizontal destination squares > > D|=FileMoves[j>>3][F]<<(j&7); > >What I'd like to know if anyone has tried to compare this method with rotated >bitboards and I'd like to know if this is a lot slower (or faster;). I _must_ do >this loop (which can be optimized a little...) for every rook but I don't have >to update rotated bitboards at all after I make moves. Maybe the net speed is >quite equal and depends on move ordering and so on...Opinions? > >Severi Hi Severi, Although I already have posted my source code, here it is again. It is very easy to understand and is added to your code in some minutes. Enjoy. Alessandro ------------------------------------------------------------------------------------------ Attack Detection with Bitboards by Alessandro Damiani (adamiani@econophone.ch) It is Freeware. ------------------------------------------------------------------------------------------ Needed global data: BitBoard AFRhorizontal[64][256], AFRvertical[64][256], AFBrightup[64][256], AFBrightdown[64][256]; with AFR: AttackFromRook AFB: AttackFromBishop unsigned int SlideIndexH[8], // horizontal SlideIndexV[8], // vertical SlideIndexRU[16], // right up (RU) SlideIndexRD[16]; // right down (RD) Incremental work: I use the two routines RemovePiece(.) and SetPiece(.) in Make(.)/Unmake(.). Here is the part concerning attack detection: void RemovePiece (Square s, Piece *p) int row, file; unsigned int a, b; row= s>>3; file= s & 7; // SlideIndex: SlideIndexH[row]^= a= 1<<(7-file); SlideIndexV[file]^= b= 1<<(7-row); SlideIndexRU[row+file]^= a; SlideIndexRD[7-row+file]^= b; } void SetPiece (Square s, Piece p) { int row, file; unsigned int a, b; row= s>>3; file= s & 7; // SlideIndex: SlideIndexH[row]|= a= 1<<(7-file); SlideIndexV[file]|= b= 1<<(7-row); SlideIndexRU[row+file]|= a; SlideIndexRD[7-row+file]|= b; } Macros used in the search and evaluation function: #define AttackRank(s) (AFRhorizontal[s][SlideIndexH[s>>3]]) #define AttackFile(s) (AFRvertical[s][SlideIndexV[s&7]]) #define AttackDiagRightUp(s) (AFBrightup[s][SlideIndexRU[(s>>3)+(s&7)]]) #define AttackDiagRightDown(s) (AFBrightdown[s][SlideIndexRD[7-(s>>3)+(s&7)]]) #define AttackFromBishop(s) (AttackDiagRightUp(s)|AttackDiagRightDown(s)) #define AttackFromRook(s) (AttackRank(s)|AttackFile(s)) #define AttackFromQueen(s) (AttackFromBishop(s)|AttackFromRook(s)) The following program generates the attack tables AFRhorizontal, AFRvertical, AFBrightup, AFBrightdown. "SquareBoard[s]" is the bitboard with bit number s set to one. Square 0 is at the top left corner. #include <stdio.h> #include "system.h" #include "bitboard.h" #define SHIFTRIGHT(b) (((b) & ~FILEH)>>1) #define SHIFTLEFT(b) (((b) & ~FILEA)<<1) #define SHIFTDOWN(b) ((b)>>8) #define SHIFTUP(b) ((b)<<8) #define SHIFTRIGHTDOWN(b) SHIFTDOWN(SHIFTRIGHT(b)) #define SHIFTLEFTDOWN(b) SHIFTDOWN(SHIFTLEFT(b)) #define SHIFTRIGHTUP(b) SHIFTUP(SHIFTRIGHT(b)) #define SHIFTLEFTUP(b) SHIFTUP(SHIFTLEFT(b)) BitBoard AFRhorizontal[64][256], AFRvertical[64][256], AFBrightup[64][256], AFBrightdown[64][256]; BitBoard IndexToAFRhorizontal (int s, unsigned int i) { BitBoard a, x; unsigned int t; a= 0; // to the right: x= SHIFTRIGHT(SquareBoard[s]); t= (unsigned int) 1<<(7-(s&7)-1); while (x) { a|= x; if (t&i) x= 0; else { x= SHIFTRIGHT(x); t>>= 1; } }; // to the left: x= SHIFTLEFT(SquareBoard[s]); t= (unsigned int) 1<<(7-(s&7)+1); while (x) { a|= x; if (t&i) x= 0; else { x= SHIFTLEFT(x); t<<= 1; } }; return a; } BitBoard IndexToAFRvertical (int s, unsigned int i) { BitBoard a, x; unsigned int t; a= 0; // downward: x= SHIFTDOWN(SquareBoard[s]); t= (unsigned int) 1<<(7-(s>>3)-1); while (x) { a|= x; if (t&i) x= 0; else { x= SHIFTDOWN(x); t>>= 1; } }; // upward: x= SHIFTUP(SquareBoard[s]); t= (unsigned int) 1<<(7-(s>>3)+1); while (x) { a|= x; if (t&i) x= 0; else { x= SHIFTUP(x); t<<= 1; } }; return a; } BitBoard IndexToAFBrightup (int s, unsigned int i) { BitBoard a, x; unsigned int t; a= 0; // right up: x= SHIFTRIGHTUP(SquareBoard[s]); t= (unsigned int) 1<<(7-(s&7)-1); while (x) { a|= x; if (t&i) x= 0; else { x= SHIFTRIGHTUP(x); t>>= 1; } }; // left down: x= SHIFTLEFTDOWN(SquareBoard[s]); t= (unsigned int) 1<<(7-(s&7)+1); while (x) { a|= x; if (t&i) x= 0; else { x= SHIFTLEFTDOWN(x); t<<= 1; } }; return a; } BitBoard IndexToAFBrightdown (int s, unsigned int i) { BitBoard a, x; unsigned int t; a= 0; // right down: x= SHIFTRIGHTDOWN(SquareBoard[s]); t= (unsigned int) 1<<(7-(s>>3)-1); while (x) { a|= x; if (t&i) x= 0; else { x= SHIFTRIGHTDOWN(x); t>>= 1; } }; // left up: x= SHIFTLEFTUP(SquareBoard[s]); t= (unsigned int) 1<<(7-(s>>3)+1); while (x) { a|= x; if (t&i) x= 0; else { x= SHIFTLEFTUP(x); t<<= 1; } }; return a; } void PrintBitBoard (BitBoard b) { int i; for (i=0; i<64; i++) { if ((i & 7)==0) printf("\n"); if (b & SquareBoard[i]) printf("1"); else printf("0"); }; printf("\n"); } void delay (void) { long i; i= 0; while (i<555555555) { i= i+1; } } int main (void) { unsigned int i; int s; FILE *f; int n; InitBitBoards(); printf("generating attack tables\n"); for (s=0; s<64; s++) { for (i=0; i<256; i++) { AFRhorizontal[s][i]= IndexToAFRhorizontal(s,i); AFRvertical[s][i] = IndexToAFRvertical(s,i); AFBrightdown[s][i] = IndexToAFBrightdown(s,i); AFBrightup[s][i] = IndexToAFBrightup(s,i); }; printf("."); }; printf("ok.\n"); printf("writing to disk: AFRH "); f= fopen("AFRH","wb"); if (f) { n= fwrite(AFRhorizontal,sizeof(BitBoard),64*256,f); if (n<64*256) printf("failure.\n"); else printf("ok.\n"); n= fclose(f); } else printf("failure.\n"); printf("writing to disk: AFRV "); f= fopen("AFRV","wb"); if (f) { n= fwrite(AFRvertical,sizeof(BitBoard),64*256,f); if (n<64*256) printf("failure.\n"); else printf("ok.\n"); n= fclose(f); } else printf("failure.\n"); printf("writing to disk: AFBRD "); f= fopen("AFBRD","wb"); if (f) { n= fwrite(AFBrightdown,sizeof(BitBoard),64*256,f); if (n<64*256) printf("failure.\n"); else printf("ok.\n"); n= fclose(f); } else printf("failure.\n"); printf("writing to disk: AFBRU "); f= fopen("AFBRU","wb"); if (f) { n= fwrite(AFBrightup,sizeof(BitBoard),64*256,f); if (n<64*256) printf("failure.\n"); else printf("ok.\n"); n= fclose(f); } else printf("failure.\n"); return 0; }
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.