Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Bitboards, pre-computing moves, and blocked squares?

Author: James Swafford

Date: 10:28:40 11/30/04

Go up one level in this thread


On November 30, 2004 at 13:25:08, James Swafford wrote:

Here's some code to precompute those arrays.  I don't claim
it's the most elegant way, but it does work- been using it
a long time.

--
James



   // precompute rank_attacks[][]
   // the idea is: standing on square <sq>, with a rank bitmap (8 bit) of <ind>,
   // rank_attack[sq][ind] contains the precomputed Bitmap of rook moves, up to
   // and including the nearest piece on each side.

   for (c=0;c<64;c++) {
      for (k=0;k<256;k++) {
         rank_attacks[c][k]=0;
         // first go left
         f = c&7;
         for (t=f-1,cnt=1;t>=0;t--,cnt++) {
            rank_attacks[c][k] |= bm_mask[c-cnt];
            // stop here if we hit a piece.
            if (k &  (int)pow(2.0,t)) {
               break;
            }
         }
         // now go right
         for (t=f+1,cnt=1;t<=7;t++,cnt++) {
            rank_attacks[c][k] |= bm_mask[c+cnt];
            // stop here if we hit a piece.
            if (k & (int)pow(2.0,t)) {
               break;
            }
         }
      }
   }

   // precompute file_attacks[][]
   for (c=0;c<64;c++) {
      for (k=0;k<256;k++) {
         file_attacks[c][k]=0;
         file_mobility[c][k]=0;
         // first go up
         r = c >> 3;
         for (t=r-1,cnt=1;t>=0;t--,cnt++) {
            file_attacks[c][k] |= bm_mask[c-cnt*8];
            file_mobility[c][k]++;
            // stop here if we hit a piece.
            if (k & (int)pow(2.0,t)) {
               break;
            }
         }
         // now go down
         for (t=r+1,cnt=1;t<=7;t++,cnt++) {
            file_attacks[c][k] |= bm_mask[c+cnt*8];
            file_mobility[c][k]++;
            // stop here if we hit a piece.
            if (k & (int)pow(2.0,t)) {
               break;
            }
         }
      }
   }

   // precompute a1h8 attacks
   int upper_limit;
   for (c=0;c<64;c++) {
      // upper limit is not 256 (2^8), but 2^diag_length
      upper_limit=(int)pow(2.0,Position::diag_length[Position::diag_a1h8[c]]);
      for (k=0;k<upper_limit;k++) {
         diag_a1h8_attacks[c][k]=0;
         // first go up right (-7)
         r = c >> 3;
         if ((c & 7) != 7) {
            for (t=r-1,cnt=1;t>=0;t--,cnt++) {
               diag_a1h8_attacks[c][k] |= bm_mask[c-cnt*7];
               // stop if we hit a piece
               // diag_length
               if (k & (int)pow(2.0,cnt-1+Position::diag_a1h8_start[c])) {
                  break;
               }
               // stop if we hit a boundary
               if (((c-cnt*7)&7)==7) {
                  break;
               }
            }
         }

         // now go down left (+7)
         if ((c & 7) != 0) {
            for (t=r+1,cnt=1;t<=7;t++,cnt++) {
               diag_a1h8_attacks[c][k] |= bm_mask[c+cnt*7];
               // stop if we hit a piece
               if (k & (int)pow(2.0,Position::diag_a1h8_start[c]-cnt-1)) {
                  break;
               }
               // stop if we hit a boundary
               if (((c+cnt*7)&7)==0) {
                  break;
               }
            }
         }
      }
   }

   // precompute h1a8 attacks
   for (c=0;c<64;c++) {
      upper_limit=(int)pow(2.0,Position::diag_length[Position::diag_h1a8[c]]);
      for (k=0;k<upper_limit;k++) {
         diag_h1a8_attacks[c][k]=0;
         // first go up and left (-9)
         r = c >> 3;
         if ((c & 7) != 0) {
            for (t=r-1,cnt=1;t>=0;t--,cnt++) {
               diag_h1a8_attacks[c][k] |= bm_mask[c-cnt*9];
               if (k & (int)pow(2.0,Position::diag_h1a8_start[c]-cnt-1)) {
                  break;
               }
               // stop if we hit a boundary
               if (((c-cnt*9)&7)==0) {
                  break;
               }
            }
         }

         // now down down and right (+9)
         if ((c & 7) != 7) {
            for (t=r+1,cnt=1;t<=7;t++,cnt++) {
               diag_h1a8_attacks[c][k] |= bm_mask[c+cnt*9];
               if (k & (int)pow(2.0,cnt-1+Position::diag_h1a8_start[c])) {
                  break;
               }
               // stop if we hit a boundary
               if (((c+cnt*9)&7)==7) {
                  break;
               }
            }
         }
      }
   }


>On November 30, 2004 at 12:51:38, Andrew N. Hunt wrote:
>
>>Hi!
>>
>>I've recently implemented bitboards (standard and rotated) and have a question
>>about pre-computing moves which contain blocked squares. Let's say I have the
>>occupied rank:
>>
>>bQ, wN, _, wR, _, bP, bN, _
>>
>>and I want to find the valid moves for the white Rook. How do I handle modifying
>>its bitboard rank: 11010110 to remove the blocked squares and only store the
>>available squares: 01101100? (which I can then And with the white/black pieces
>>to find valid Rook moves)
>>
>>Maybe I'm missing something obvious... :-?
>
>You need to precompute a two dimension array
>Bitboard rank_moves[64][256].  The first index is the square
>the rook is on.  The second index is the state of the rank
>(in this case 11010110 base 2).
>
>You'll need a similar array for files and diagonals
>(one for the a1->h8 direction and one more for the h1->a8
>direction).
>
>Just build these arrays in your program initialization
>by doing some looping.
>
>Hope that helps...
>--
>James
>
>
>>
>>Many thanks!
>>
>>
>>
>>
>>
>>ah.
>>
>>--------------------------------------------------------------------=
>>Andy Hunt
>>Manager, Electronic Documentation
>>Wolfram Research, Inc.
>>Voice: 217-398-0700  ext.260;  Fax:  217-398-0747
>>Email: andy@wolfram.com; http://www.wolfram.com/
>>--------------------------------------------------------------------=
>>
>>Power corrupts.  Absolute power is kind of neat.
>> -- John Lehman, Secretary of the Navy, 1981-1987



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.