Computer Chess Club Archives


Search

Terms

Messages

Subject: Re: Basic bitboard representation in C (shifting)

Author: Stuart Cracraft

Date: 15:29:24 01/06/06

Go up one level in this thread


On January 06, 2006 at 12:49:25, frogMeSebastian wrote:

>Hello all
>
>I have read a lot about the idea of bitboards and its use in chess programming,
>I fail, however, to get the idea of how to implement it in C.
>
>I have got something like this:
>  unsigned long long int bb_WhitePawns
>
>Now let's say there is one single Pawn on A1. If I simply do
>  bb_WhitePawns = 1000..0 (63 0)
>Then
>  printf(" %i", bb_WhitePawns >> 1);
>would not return '0100..00' but some nonsense integer value.
>
>It seems to me that the compiler does not interprete the value as a 64-bit-word.
>What am I doing wrong?

Hi - I do this (which is Crafty/GNU5-like as of a few years back).

//The basic 64 bit board on a 32-bit machine. Maybe someday I'll own a 64-bit.

#define BITS
#define GNU_COMPILER

#ifdef MS_COMPILER
typedef unsigned __int64 BitBoard;
#endif
#ifdef GNU_COMPILER
typedef unsigned long long BitBoard;
#endif

// Set bit at place i in bitboard b
#define SETBIT(b,i)   ((b) |= BitPosArray[i])
//Unset it
#define CLEARBIT(b,i) ((b) &= NotBitPosArray[i])

#ifdef BITS
BitBoard b[2][7];   // the various piece location bitboards for both sides
BitBoard BitPosArray[64];    // set bits
BitBoard NotBitPosArray[64];  // the inverse of that
#endif

#ifdef BITS
unsigned char lzArray[65536];
unsigned char BitCount[65536];

#ifdef MS_COMPILER
__forceinline static unsigned char leadz (BitBoard b)
#else
inline static unsigned char leadz (BitBoard b)
#endif
/**************************************************************************
*
*  Returns the leading bit in a bitboard.  Leftmost bit is 0 and
*  rightmost bit is 63.  Thanks to Robert Hyatt for this algorithm.
*
***************************************************************************/
{
  if (b >> 48) return lzArray[b >> 48];
  if (b >> 32) return lzArray[b >> 32] + 16;
  if (b >> 16) return lzArray[b >> 16] + 32;
  return lzArray[b] + 48;
}
#ifdef MS_COMPILER
__forceinline static unsigned char nbits (BitBoard b)
#else
inline static unsigned char nbits (BitBoard b)
#endif
/***************************************************************************
*
*  Count the number of bits in b.
*
***************************************************************************/
{
  return BitCount[b>>48] + BitCount[(b>>32) & 0xffff]
    + BitCount[(b>>16) & 0xffff] + BitCount[b & 0xffff];
}
void initbitcount (void)
/**************************************************************************
*
*  The BitCount array returns the no. of bits present in the 16 bit
*  input argument.  This is use for counting the number of bits set
*  in a BitBoard (e.g. for mobility count).
*
**************************************************************************/
{
  int i, j, n;

  BitCount[0] = 0;
  BitCount[1] = 1;
  i = 1;
  for (n = 2; n <= 16; n++)
  {
    i <<= 1;
    for (j = i; j <= i + (i-1); j++)
      BitCount[j] = 1 + BitCount[j - i];
  }
}
#define NBITS 16

void initlzarray (void)
/***************************************************************************
*
*  The lzArray is created.  This array is used when the position
*  of the leading non-zero bit is required.  The convention used
*  is that the leftmost bit is considered as position 0 and the
*  rightmost bit position 63.
*
***************************************************************************/
{
  int i, j, s, n;

  s = n = 1;
  for (i = 0; i < NBITS; i++)
  {
    for (j = s; j < s + n; j++)
      lzArray[j] = NBITS - 1 - i;
    s += n;
    n += n;
  }
}
void initbitposarray (void)
/***************************************************************************
*
*  BitPosArray[i] returns the bitboard whose ith bit is set to 1
*  and every other bits 0.  This ought to be faster than doing
*  shifting all the time (I think).
*  Also compute the NotBitPosArray = ~BitPosArray.
*
***************************************************************************/
{
  BitBoard b;
  int i;

  b = (BitBoard) 1;
  for (i = 63; i >= 0; i--, b <<= 1)
  {
    BitPosArray[i] = b;
    NotBitPosArray[i] = ~b;
  }
}
void ShowBitBoard (BitBoard *b)
/*****************************************************************************
*
* Just to print a lousy ascii board
*
*****************************************************************************/
{
  int r, c;

  printf ("\n");
  for (r = 56; r >= 0; r -= 8)
  {
    for (c = 0; c < 8; c++)
    {
      if (*b & BitPosArray[r + c])
        printf ("1 ");
      else
        printf (". ");
    }
    printf ("\n");
  }
  printf ("\n");
}

void bb_pbd (void)
/*****************************************************************************
*
*  Display the board.  Not only that but display some useful information
*  like whether enpassant is legal and castling state.
*
*****************************************************************************/
{
  int r, c, sq, cl=0;
#ifdef NEVER
  printf ("\n");
  if (board.side == white)
    printf ("white  ");
  else
    printf ("black  ");

  if (board.flag & WKINGCASTLE)
    printf ("K");
  if (board.flag & WQUEENCASTLE)
    printf ("Q");
  if (board.flag & BKINGCASTLE)
    printf ("k");
  if (board.flag & BQUEENCASTLE)
    printf ("q");

  if (board.ep > -1)
    printf ("  %s", algbr[board.ep]);

  printf ("\n");
#endif
  for (r = 56; r >= 0; r -= 8)
  {
    for (c = 0; c < 8; c++)
    {
      sq = r + c;
      if (b[white][pawn] & BitPosArray[sq])
        printf ("WP ");
      else if (b[white][knight] & BitPosArray[sq])
        printf ("WN ");
      else if (b[white][bishop] & BitPosArray[sq])
        printf ("WB ");
      else if (b[white][rook] & BitPosArray[sq])
        printf ("WR ");
      else if (b[white][queen] & BitPosArray[sq])
        printf ("WQ ");
      else if (b[white][king] & BitPosArray[sq])
        printf ("WK ");
      else if (b[black][pawn] & BitPosArray[sq])
        printf ("BP ");
      else if (b[black][knight] & BitPosArray[sq])
        printf ("BN ");
      else if (b[black][bishop] & BitPosArray[sq])
        printf ("BB ");
      else if (b[black][rook]   & BitPosArray[sq])
        printf ("BR ");
      else if (b[black][queen]  & BitPosArray[sq])
        printf ("BQ ");
      else if (b[black][king]   & BitPosArray[sq])
        printf ("BK ");
      else
        printf ("%s ",cl==0?"--":"**");
      cl^=1;
    }
    printf ("\n");
    cl^=1;
  }
  printf ("\n");
  printf("stage %.f, %s to move, computer plays
%s\n",stage,stm==white?"white":"black",computerplays==white?"white":"bla
ck");
  fprintf(lfp,"stage %.f, %s to move, computer plays
%s\n",stage,stm==white?"white":"black",computerplays==white?"white"
:"black");
#ifdef BITS
  printf("white pawns: %d white pieces: %d\n",
    nbits(b[white][pawn]),
    nbits(b[white][knight]|b[white][bishop]|b[white][rook]|b[white][queen]));
  printf("black pawns: %d black pieces: %d\n",
    nbits(b[black][pawn]),
    nbits(b[black][knight]|b[black][bishop]|b[black][rook]|b[black][queen]));
#endif
#ifndef BITS
  printf("white pawns: %d white pieces: %d\n",
        piecelist[white][pawn],piecelist[white][knight]+
         piecelist[white][bishop]+piecelist[white][rook]+
         piecelist[white][queen]);
  printf("black pawns: %d black pieces: %d\n",
        piecelist[black][pawn],piecelist[black][knight]+
         piecelist[black][bishop]+piecelist[black][rook]+
         piecelist[black][queen]);
#endif
}
#endif

Enjoy,

Stuart



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.