Exemple #1
0
short SqAtakd (short sq, short side)
/**************************************************************************
 *
 *  To determine if sq is attacked by any pieces from side.
 *
 **************************************************************************/
{
   register BitBoard *a, b, *c, d, blocker;
   int t;
   
   a = board.b[side];

   /* Knights */
   if (a[knight] & MoveArray[knight][sq])
      return (true);

   /* Kings */
   if (a[king] & MoveArray[king][sq])
      return (true);

   /* Pawns */
   if (a[pawn] & MoveArray[ptype[1^side]][sq])
      return (true);
      
   c = FromToRay[sq];
   blocker = board.blocker;

   /* Bishops & Queen */
   b = (a[bishop] | a[queen]) & MoveArray[bishop][sq];
   d = ~b & blocker; 
   while (b)
   {
      t = leadz (b);
      if (!(c[t] & d))
         return (true);
      CLEARBIT (b, t); 
   }

   /* Rooks & Queen */
   b = (a[rook] | a[queen]) & MoveArray[rook][sq];
   d = ~b & blocker;
   while (b)
   {
      t = leadz (b);
      if (!(c[t] & d))
         return (true);
      CLEARBIT (b, t); 
   }
   return (false);
}
Exemple #2
0
void AddXrayPiece (int t, int sq, int side, BitBoard *b, BitBoard *c)
/***************************************************************************
 *
 *  The purpose of this routine is to find a piece which attack through
 *  another piece (e.g. two rooks, Q+B, B+P, etc.)  Side is the side attacking
 *  the square where the swapping is to be done.
 *
 ***************************************************************************/
{
   int dir, nsq, piece;
   BitBoard a;

   dir = directions[t][sq];
   a = Ray[sq][dir] & board.blocker;
   if (a == NULLBITBOARD)
      return;
   nsq = (t < sq ? leadz (a) : trailz (a));
   piece = cboard[nsq];
   if ((piece == queen) || (piece == rook && dir > 3) || 
			    (piece == bishop && dir < 4))
   {
      if (BitPosArray[nsq] & board.friends[side])
         *b |= BitPosArray[nsq];
      else
         *c |= BitPosArray[nsq];
   }
   return;
}
Exemple #3
0
BitBoard AttackTo (int sq, int side)
/***************************************************************************
 *
 *  Generate a bitboard of all squares with pieces belonging to side
 *  which attack sq.
 *
 ***************************************************************************/
{
   register BitBoard *a, b, *c, e, blocker;
   int t;
   
   a = board.b[side];

   /* Knights */
   e = (a[knight] & MoveArray[knight][sq]); 	

   /* Kings */
   e |= (a[king] & MoveArray[king][sq]); 	

   /* Pawns */
   e |= (a[pawn] & MoveArray[ptype[1^side]][sq]);
      
   c = FromToRay[sq];
   blocker = board.blocker;

   /* Bishops & Queen */
   b = (a[bishop] | a[queen]) & MoveArray[bishop][sq];
   while (b)
   {
      t = leadz (b);
      CLEARBIT (b, t); 
      if (!(c[t] & blocker & NotBitPosArray[t]))
	 e |= BitPosArray[t];
   }

   /* Rooks & Queen */
   b = (a[rook] | a[queen]) & MoveArray[rook][sq];
   while (b)
   {
      t = leadz (b);
      CLEARBIT (b, t); 
      if (!(c[t] & blocker & NotBitPosArray[t]))
	 e |= BitPosArray[t];
   }

   return (e);
}
Exemple #4
0
int PinnedOnKing (int sq, int side)
/***************************************************************************
 *
 *  Determine if the piece on sq is pinned against the King.
 *  Side is the color of the piece.  
 *  Caveat: PinnedOnKing should only be called by GenCheckEscapes().
 *  The more generic FindPins() function should be used for evaluating
 *  pins against other pieces.
 *
 ***************************************************************************/
{
   int xside;
   int KingSq, dir, sq1;
   BitBoard b, blocker;

   KingSq = board.king[side];
   if ((dir = directions[KingSq][sq]) == -1)
      return (false);

   xside = 1 ^ side;
   blocker = board.blocker;
 
   /*  Path from piece to king is blocked, so no pin */
   if (FromToRay[KingSq][sq] & NotBitPosArray[sq] & blocker)
      return (false);
   b = (Ray[KingSq][dir] ^ FromToRay[KingSq][sq]) & blocker;
   if (b == NULLBITBOARD)
      return (false);
   sq1 = (sq > KingSq ? leadz (b) : trailz (b));

   /*  If diagonal  */
   if (dir <= 3 && 
	BitPosArray[sq1] & (board.b[xside][queen] | board.b[xside][bishop]))
      return (true);
   
   /*  Rank / file  */  
   if (dir >= 4 && 
	BitPosArray[sq1] & (board.b[xside][queen] | board.b[xside][rook]))
      return (true);

   return (false);
}
Exemple #5
0
int SwapOff (int move)
/****************************************************************************
 *
 *  A Static Exchange Evaluator (or SEE for short).
 *  First determine the target square.  Create a bitboard of all squares
 *  attacking the target square for both sides.  Using these 2 bitboards,
 *  we take turn making captures from smallest piece to largest piece.
 *  When a sliding piece makes a capture, we check behind it to see if
 *  another attacker piece has been exposed.  If so, add this to the bitboard
 *  as well.  When performing the "captures", we stop if one side is ahead
 *  and doesn't need to capture, a form of pseudo-minimaxing.
 *
 ****************************************************************************/
{
   int f, t, sq, piece, lastval;
   int side, xside; 
   int swaplist[MAXPLYDEPTH], n;
   BitBoard b, c, *d, *e, r;

   f = FROMSQ (move);
   t = TOSQ (move);
   side = ((board.friends[white] & BitPosArray[f]) ? white : black);
   xside = 1^side;

   /*  Squares attacking t for side and xside  */
   b = AttackTo (t, side);
   c = AttackTo (t, xside);
   CLEARBIT(b, f);
   if (xray[cboard[f]])
      AddXrayPiece (t, f, side, &b, &c);

   d = board.b[side];
   e = board.b[xside]; 
   if (move & PROMOTION)
   {
      swaplist[0] = Value[PROMOTEPIECE (move)] - ValueP;
      lastval = -Value[PROMOTEPIECE (move)];
   }
   else
   {
      swaplist[0] = (move & ENPASSANT ? ValueP : Value[cboard[t]]);
      lastval = -Value[cboard[f]];
   }
   n = 1;
   while (1)
   {
      if (c == NULLBITBOARD)
         break;
      for (piece = pawn; piece <= king; piece++)
      {
         r = c & e[piece]; 
	 if (r)
         {
	    sq = leadz (r);
	    CLEARBIT (c, sq);
	    if (xray[piece])
	       AddXrayPiece (t, sq, xside, &c, &b);
	    swaplist[n] = swaplist[n-1] + lastval;
            n++;
	    lastval = Value[piece];
	    break;
         }
      }

      if (b == NULLBITBOARD)
         break;
      for (piece = pawn; piece <= king; piece++)
      {
         r = b & d[piece]; 
	 if (r)
         {
	    sq = leadz (r);
	    CLEARBIT (b, sq);
	    if (xray[piece])
	       AddXrayPiece (t, sq, side, &b, &c);
	    swaplist[n] = swaplist[n-1] + lastval;
            n++;
	    lastval = -Value[piece];
	    break;
         }
      }
   }

/****************************************************************************
 *
 *  At this stage, we have the swap scores in a list.  We just need to 
 *  mini-max the scores from the bottom up to the top of the list.
 *
 ****************************************************************************/
   --n;
   while (n)
   {
      if (n & 1)
      {
         if (swaplist[n] <= swaplist[n-1])
	    swaplist[n-1] = swaplist[n]; 
      }
      else
      {
         if (swaplist[n] >= swaplist[n-1])
	    swaplist[n-1] = swaplist[n]; 
      }
      --n;
   }
   return (swaplist[0]);
}
Exemple #6
0
int ParseEPD (char *p)
/**************************************************************************
 *   
 *  Parses an EPD input line.  A few global variables are updated e.g.
 *  current board, side to move, en passant, castling status, etc.
 *
 **************************************************************************/
{
   int r, c, sq;
   char *str_p;

   r = 56;
   c = 0;
   memset (&board, 0, sizeof (board));

   while (p && *p != ' ')
   {
     sq = r + c;
     switch (*p)
     {
        case 'P' :  SETBIT (board.b[white][pawn], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    board.material[white] += ValueP;
		    break;	
        case 'N' :  SETBIT (board.b[white][knight], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    board.material[white] += ValueN;
		    break;	
        case 'B' :  SETBIT (board.b[white][bishop], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    board.material[white] += ValueB;
		    break;	
        case 'R' :  SETBIT (board.b[white][rook], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    board.material[white] += ValueR;
		    break;	
        case 'Q' :  SETBIT (board.b[white][queen], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    board.material[white] += ValueQ;
		    break;	
        case 'K' :  SETBIT (board.b[white][king], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    break;	
        case 'p' :  SETBIT (board.b[black][pawn], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    board.material[black] += ValueP;
		    break;	
        case 'n' :  SETBIT (board.b[black][knight], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    board.material[black] += ValueN;
		    break;	
        case 'b' :  SETBIT (board.b[black][bishop], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    board.material[black] += ValueB;
		    break;	
        case 'r' :  SETBIT (board.b[black][rook], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    board.material[black] += ValueR;
		    break;	
        case 'q' :  SETBIT (board.b[black][queen], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
                    board.material[black] += ValueQ;
		    break;	
        case 'k' :  SETBIT (board.b[black][king], sq);
		    SETBIT (board.blockerr90, r90[sq]);
		    SETBIT (board.blockerr45, r45[sq]);
		    SETBIT (board.blockerr315, r315[sq]);
		    break;	
        case '/' :  r -= 8;
	 	    c = -1;
		    break;
        default  :  break;
     }
     if (isdigit (*p))
        c += (*p - '0');
     else
        c++;

     /* 
      * Special case, a trailing "/" is accepted on the
      * end of the board settings.
      */

     if (r == -8 && p[1] == ' ')
	     r = 0;

     if (r < 0 || c > 8) return EPD_ERROR;
     if (c == 8 && p[1] != '/' && p[1] != ' ') return EPD_ERROR;
     p++;
   }

   board.pmaterial[white] = board.material[white] - 
				nbits(board.b[white][pawn]) * ValueP;
   board.pmaterial[black] = board.material[black] - 
				nbits(board.b[black][pawn]) * ValueP;
   board.king[white] = leadz (board.b[white][king]);
   board.king[black] = leadz (board.b[black][king]);
   UpdateFriends (); 
   UpdateCBoard ();
   UpdateMvboard ();

   /*  Get side to move  */
   if (!++p) return EPD_ERROR;
   if      (*p == 'w') board.side = white; 
   else if (*p == 'b') board.side = black;
   else return EPD_ERROR;

   /* Isn't this one cute? */
   if (!++p || *p != ' ' || !++p) return EPD_ERROR;
  
   /*  Castling status  */
   while (p && *p != ' ') {
      if      (*p == 'K') board.flag |= WKINGCASTLE;
      else if (*p == 'Q') board.flag |= WQUEENCASTLE;
      else if (*p == 'k') board.flag |= BKINGCASTLE;
      else if (*p == 'q') board.flag |= BQUEENCASTLE;
      else if (*p == '-') { p++; break; }
      else return EPD_ERROR;
      p++;
   }
   if (!p || *p != ' ' || !++p) return EPD_ERROR;

   /*
    * En passant square, can only be '-' or [a-h][36]
    * In fact, one could add more sanity checks here.
    */
   if (*p != '-') {
      if (!p[1] || *p < 'a' || *p > 'h' ||
	  !(p[1] == '3' || p[1] == '6')) return EPD_ERROR;
      board.ep = (*p - 'a') + (p[1] - '1')*8;
      p++;
   } else {
      board.ep = -1;
   }

   solution[0] = '\0';
   id[0] = '\0';

   if (!++p) return EPD_SUCCESS;

   /* The opcodes are optional, so we should not generate errors here */

   /*  Read in best move; "bm" operator */
   str_p = strstr(p, "bm");
   if (str_p) sscanf (str_p, "bm %63[^;];", solution); 

   /*  Read in the description; "id" operator */
   str_p = strstr(p, "id");
   if (str_p) sscanf (p, "id %31[^;];", id);

   phase = PHASE;

   return EPD_SUCCESS;
}
Exemple #7
0
void GenAtaks (void)
/*************************************************************************
 *
 *  To generate the attack table.
 *  Ataks[side][0] holds the total attack tables.
 *  Ataks[side][pawn] holds the BitBoard of squares attacked by all pawns.
 *
 *************************************************************************/
{
   int side; 
   int sq;
   register BitBoard *a, b, *t, *a0;

   memset (Ataks, 0, sizeof (Ataks)); 
   for (side = white; side <= black; side++)
   {
      a = board.b[side];

      /* Knight */
      t = &Ataks[side][knight];
      b = a[knight];
      while (b)
      {
         sq = leadz (b);
         CLEARBIT (b, sq);
         *t |= MoveArray[knight][sq];
      }

      /* Bishops */
      t = &Ataks[side][bishop];
      b = a[bishop];
      while (b)
      {
	 sq = leadz (b);
	 CLEARBIT (b, sq);
	 *t |= BishopAttack(sq);
      }

      /*  Rooks */
      t = &Ataks[side][rook];
      b = a[rook];
      while (b)
      {
	 sq = leadz (b);
	 CLEARBIT (b, sq);
	 *t |= RookAttack(sq);
      }

      /*  Queen  */
      t = &Ataks[side][queen];
      b = a[queen];
      while (b)
      {
	 sq = leadz (b);
	 CLEARBIT (b, sq);
	 *t |= QueenAttack(sq);
      }

      /* King */
      t = &Ataks[side][king];
      b = a[king];
      while (b)
      {
         sq = leadz (b);
         CLEARBIT (b, sq);
         *t |= MoveArray[king][sq];
      }

      /*  pawns  */
      t = &Ataks[side][pawn];
      if (side == white)
      {
         b = board.b[white][pawn] & ~FileBit[0];
         *t |= (b >> 7);
         b = board.b[white][pawn] & ~FileBit[7];
         *t |= (b >> 9);
      }
      else
      {