Ejemplo n.º 1
0
bool piece_attack_king(const board_t * board, int piece, int from, int king) {

   const inc_t * inc_ptr;
   int code;
   const int * delta_ptr;
   int delta, inc;
   int to;
   int sq;

   ASSERT(board!=NULL);
   ASSERT(piece_is_ok(piece));
   ASSERT(SQUARE_IS_OK(from));
   ASSERT(SQUARE_IS_OK(king));

   inc_ptr = PIECE_INC(piece);

   code = PieceCode[piece];
   ASSERT(code>=0&&code<4);

   if (PIECE_IS_SLIDER(piece)) {

      for (delta_ptr = PieceDeltaDelta[code][DeltaOffset+(king-from)]; (delta=*delta_ptr) != DeltaNone; delta_ptr++) {

         ASSERT(delta_is_ok(delta));

         inc = DeltaIncLine[DeltaOffset+delta];
         ASSERT(inc!=IncNone);

         to = from + delta;

         sq = from;
         do {
            sq += inc;
         //   if (sq == to && SQUARE_IS_OK(to)) {
         //      ASSERT(DISTANCE(to,king)==1);
         //      return true; 
			if (DISTANCE(sq,king)<=2){
				  return true; 
			}
            
         } while (board->square[sq] == Empty);
      }

   } else { // non-slider

      for (delta_ptr = PieceDeltaDelta[code][DeltaOffset+(king-from)]; (delta=*delta_ptr) != DeltaNone; delta_ptr++) {

         ASSERT(delta_is_ok(delta));

         to = from + delta;

         if (SQUARE_IS_OK(to)) {
            ASSERT(DISTANCE(to,king)==1);
            return true;
         }
      }
   }

   return false;
}
Ejemplo n.º 2
0
void attack_init() {

    int delta;
    int dir, inc, dist;

    for (delta = -128; delta < +128; delta++) {
        DeltaInc[128+delta] = IncNone;
        DeltaMask[128+delta] = 0;
    }

    DeltaMask[128-17] |= BlackPawnFlag;
    DeltaMask[128-15] |= BlackPawnFlag;

    DeltaMask[128+15] |= WhitePawnFlag;
    DeltaMask[128+17] |= WhitePawnFlag;

    for (dir = 0; dir < 8; dir++) {
        delta = KnightInc[dir];
        ASSERT(delta_is_ok(delta));
        DeltaMask[128+delta] |= KnightFlag;
    }

    for (dir = 0; dir < 4; dir++) {
        inc = BishopInc[dir];
        ASSERT(inc!=IncNone);
        for (dist = 1; dist < 8; dist++) {
            delta = inc*dist;
            ASSERT(delta_is_ok(delta));
            ASSERT(DeltaInc[128+delta]==IncNone);
            DeltaInc[128+delta] = inc;
            DeltaMask[128+delta] |= BishopFlag;
        }
    }

    for (dir = 0; dir < 4; dir++) {
        inc = RookInc[dir];
        ASSERT(inc!=IncNone);
        for (dist = 1; dist < 8; dist++) {
            delta = inc*dist;
            ASSERT(delta_is_ok(delta));
            ASSERT(DeltaInc[128+delta]==IncNone);
            DeltaInc[128+delta] = inc;
            DeltaMask[128+delta] |= RookFlag;
        }
    }

    for (dir = 0; dir < 8; dir++) {
        delta = KingInc[dir];
        ASSERT(delta_is_ok(delta));
        DeltaMask[128+delta] |= KingFlag;
    }
}
Ejemplo n.º 3
0
void vector_init() {

   int delta;
   int x, y;
   int dist, tmp;

   // Distance[]

   for (delta = 0; delta < DeltaNb; delta++) Distance[delta] = -1;

   for (y = -7; y <= +7; y++) {

      for (x = -7; x <= +7; x++) {

         delta = y * 16 + x;
         ASSERT(delta_is_ok(delta));

         dist = 0;

         tmp = x;
         if (tmp < 0) tmp = -tmp;
         if (tmp > dist) dist = tmp;

         tmp = y;
         if (tmp < 0) tmp = -tmp;
         if (tmp > dist) dist = tmp;

         Distance[DeltaOffset+delta] = dist;
      }
   }
}
Ejemplo n.º 4
0
bool piece_attack(const board_t * board, int piece, int from, int to) {

    int delta;
    int inc, sq;

    ASSERT(board_is_ok(board));
    ASSERT(piece_is_ok(piece));
    ASSERT(square_is_ok(from));
    ASSERT(square_is_ok(to));

    delta = to - from;
    ASSERT(delta_is_ok(delta));

    if ((piece & DELTA_MASK(delta)) == 0) return false; // no pseudo-attack

    if (!piece_is_slider(piece)) return true;

    inc = DELTA_INC(delta);
    ASSERT(inc_is_ok(inc));

    for (sq = from+inc; sq != to; sq += inc) {
        ASSERT(square_is_ok(sq));
        if (board->square[sq] != Empty) return false; // blocker
    }

    return true;
}
Ejemplo n.º 5
0
static void find_pins(int list[], const board_t * board) {

    int me, opp;
    int king;
    const sq_t * ptr;
    int from;
    int piece;
    int delta;
    int inc;
    int sq;
    int capture;
    int pin;

    ASSERT(list!=NULL);
    ASSERT(board!=NULL);

    // init

    me = board->turn;
    opp = COLOUR_OPP(me);

    king = KING_POS(board,opp);

    for (ptr = &board->piece[me][1]; (from=*ptr) != SquareNone; ptr++) { // HACK: no king

        piece = board->square[from];

        delta = king - from;
        ASSERT(delta_is_ok(delta));

        if (PSEUDO_ATTACK(piece,delta)) {

            ASSERT(PIECE_IS_SLIDER(piece));

            inc = DELTA_INC_LINE(delta);
            ASSERT(inc!=IncNone);

            ASSERT(SLIDER_ATTACK(piece,inc));

            sq = from;
            do sq += inc;
            while ((capture=board->square[sq]) == Empty);

            ASSERT(sq!=king);

            if (COLOUR_IS(capture,me)) {
                pin = sq;
                do sq += inc;
                while (board->square[sq] == Empty);
                if (sq == king) *list++ = pin;
            }
        }
    }

    *list = SquareNone;
}
Ejemplo n.º 6
0
static void add_attack(int piece, int king, int target) {

   int size;
   int i;

   ASSERT(piece>=0&&piece<4);
   ASSERT(delta_is_ok(king));
   ASSERT(delta_is_ok(target));

   size = PieceDeltaSize[piece][DeltaOffset+king];
   ASSERT(size>=0&&size<3);

   for (i = 0; i < size; i++) {
      if (PieceDeltaDelta[piece][DeltaOffset+king][i] == target) return; // already in the table
   }

   if (size < 2) {
      PieceDeltaDelta[piece][DeltaOffset+king][size] = target;
      size++;
      PieceDeltaSize[piece][DeltaOffset+king] = size;
   }
}
Ejemplo n.º 7
0
bool line_is_empty(const board_t * board, int from, int to) {

   int delta;
   int inc, sq;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(from));
   ASSERT(SQUARE_IS_OK(to));

   delta = to - from;
   ASSERT(delta_is_ok(delta));

   inc = DELTA_INC_ALL(delta);
   ASSERT(inc!=IncNone);

   sq = from;
   do {
      sq += inc;
      if (sq == to) return true;
   } while (board->square[sq] == Empty);

   return false; // blocker
}
Ejemplo n.º 8
0
bool move_is_pseudo(int move, board_t * board) {

    int me, opp;
    int from, to;
    int piece, capture;
    int inc, delta;

    ASSERT(move_is_ok(move));
    ASSERT(board!=NULL);

    ASSERT(!board_is_check(board));

    // special cases

    if (MOVE_IS_SPECIAL(move)) {
        return move_is_pseudo_debug(move,board);
    }

    ASSERT((move&~07777)==0);

    // init

    me = board->turn;
    opp = COLOUR_OPP(board->turn);

    // from

    from = MOVE_FROM(move);
    ASSERT(SQUARE_IS_OK(from));

    piece = board->square[from];
    if (!COLOUR_IS(piece,me)) return false;

    ASSERT(piece_is_ok(piece));

    // to

    to = MOVE_TO(move);
    ASSERT(SQUARE_IS_OK(to));

    capture = board->square[to];
    if (COLOUR_IS(capture,me)) return false;

    // move

    if (PIECE_IS_PAWN(piece)) {

        if (SQUARE_IS_PROMOTE(to)) return false;

        inc = PAWN_MOVE_INC(me);
        delta = to - from;
        ASSERT(delta_is_ok(delta));

        if (capture == Empty) {

            // pawn push

            if (delta == inc) return true;

            if (delta == (2*inc)
                    && PAWN_RANK(from,me) == Rank2
                    && board->square[from+inc] == Empty) {
                return true;
            }

        } else {

            // pawn capture

            if (delta == (inc-1) || delta == (inc+1)) return true;
        }

    } else {

        if (PIECE_ATTACK(board,piece,from,to)) return true;
    }

    return false;
}
Ejemplo n.º 9
0
void attack_set(attack_t * attack, const board_t * board) {

   int me, opp;
   const sq_t * ptr;
   int from, to;
   int inc;
   int pawn;
   int delta, piece;
   int sq;

   ASSERT(attack!=NULL);
   ASSERT(board!=NULL);

   // init

   attack->dn = 0;

   me = board->turn;
   opp = COLOUR_OPP(me);

   to = KING_POS(board,me);

   // pawn attacks

   inc = PAWN_MOVE_INC(opp);
   pawn = PAWN_MAKE(opp);

   from = to - (inc-1);
   if (board->square[from] == pawn) {
      attack->ds[attack->dn] = from;
      attack->di[attack->dn] = IncNone;
      attack->dn++;
   }

   from = to - (inc+1);
   if (board->square[from] == pawn) {
      attack->ds[attack->dn] = from;
      attack->di[attack->dn] = IncNone;
      attack->dn++;
   }

   // piece attacks

   for (ptr = &board->piece[opp][1]; (from=*ptr) != SquareNone; ptr++) { // HACK: no king

      piece = board->square[from];

      delta = to - from;
      ASSERT(delta_is_ok(delta));

      if (PSEUDO_ATTACK(piece,delta)) {

         inc = IncNone;

         if (PIECE_IS_SLIDER(piece)) {

            // check for blockers

            inc = DELTA_INC_LINE(delta);
            ASSERT(inc!=IncNone);

            sq = from;
            do sq += inc; while (board->square[sq] == Empty);

            if (sq != to) continue; // blocker => next attacker
         }

         attack->ds[attack->dn] = from;
         attack->di[attack->dn] = -inc; // HACK
         attack->dn++;
      }
   }

   attack->ds[attack->dn] = SquareNone;
   attack->di[attack->dn] = IncNone;

   // debug

   ASSERT(attack_is_ok(attack));
}
Ejemplo n.º 10
0
void attack_init() {

   int delta, inc;
   int piece;
   int dir, dist;
   int size;
   int king;
   int from, to;
   int pos;

   // clear

   for (delta = 0; delta < DeltaNb; delta++) {
      DeltaIncLine[delta] = IncNone;
      DeltaIncAll[delta] = IncNone;
      DeltaMask[delta] = 0;
   }

   for (inc = 0; inc < IncNb; inc++) {
      IncMask[inc] = 0;
   }

   // pawn attacks

   DeltaMask[DeltaOffset-17] |= BlackPawnFlag;
   DeltaMask[DeltaOffset-15] |= BlackPawnFlag;

   DeltaMask[DeltaOffset+15] |= WhitePawnFlag;
   DeltaMask[DeltaOffset+17] |= WhitePawnFlag;

   // knight attacks

   for (dir = 0; dir < 8; dir++) {

      delta = KnightInc[dir];
      ASSERT(delta_is_ok(delta));

      ASSERT(DeltaIncAll[DeltaOffset+delta]==IncNone);
      DeltaIncAll[DeltaOffset+delta] = delta;
      DeltaMask[DeltaOffset+delta] |= KnightFlag;
   }

   // bishop/queen attacks

   for (dir = 0; dir < 4; dir++) {

      inc = BishopInc[dir];
      ASSERT(inc!=IncNone);

      IncMask[IncOffset+inc] |= BishopFlag;

      for (dist = 1; dist < 8; dist++) {

         delta = inc*dist;
         ASSERT(delta_is_ok(delta));

         ASSERT(DeltaIncLine[DeltaOffset+delta]==IncNone);
         DeltaIncLine[DeltaOffset+delta] = inc;
         ASSERT(DeltaIncAll[DeltaOffset+delta]==IncNone);
         DeltaIncAll[DeltaOffset+delta] = inc;
         DeltaMask[DeltaOffset+delta] |= BishopFlag;
      }
   }

   // rook/queen attacks

   for (dir = 0; dir < 4; dir++) {

      inc = RookInc[dir];
      ASSERT(inc!=IncNone);

      IncMask[IncOffset+inc] |= RookFlag;

      for (dist = 1; dist < 8; dist++) {

         delta = inc*dist;
         ASSERT(delta_is_ok(delta));

         ASSERT(DeltaIncLine[DeltaOffset+delta]==IncNone);
         DeltaIncLine[DeltaOffset+delta] = inc;
         ASSERT(DeltaIncAll[DeltaOffset+delta]==IncNone);
         DeltaIncAll[DeltaOffset+delta] = inc;
         DeltaMask[DeltaOffset+delta] |= RookFlag;
      }
   }

   // king attacks

   for (dir = 0; dir < 8; dir++) {

      delta = KingInc[dir];
      ASSERT(delta_is_ok(delta));

      DeltaMask[DeltaOffset+delta] |= KingFlag;
   }

   // PieceCode[]

   for (piece = 0; piece < PieceNb; piece++) {
      PieceCode[piece] = -1;
   }

   PieceCode[WN] = 0;
   PieceCode[WB] = 1;
   PieceCode[WR] = 2;
   PieceCode[WQ] = 3;

   PieceCode[BN] = 0;
   PieceCode[BB] = 1;
   PieceCode[BR] = 2;
   PieceCode[BQ] = 3;

   // PieceDeltaSize[][] & PieceDeltaDelta[][][]

   for (piece = 0; piece < 4; piece++) {
      for (delta = 0; delta < 256; delta++) {
         PieceDeltaSize[piece][delta] = 0;
      }
   }

   for (king = 0; king < SquareNb; king++) {

      if (SQUARE_IS_OK(king)) {

         for (from = 0; from < SquareNb; from++) {

            if (SQUARE_IS_OK(from)) {

               // knight

               for (pos = 0; (inc=KnightInc[pos]) != IncNone; pos++) {
                  to = from + inc;
                  if (SQUARE_IS_OK(to) && DISTANCE(to,king) == 1) {
                     add_attack(0,king-from,to-from);
                  }
               }

               // bishop

               for (pos = 0; (inc=BishopInc[pos]) != IncNone; pos++) {
                  for (to = from+inc; SQUARE_IS_OK(to); to += inc) {
                     if (DISTANCE(to,king) == 1) {
                        add_attack(1,king-from,to-from);
                        break;
                     }
                  }
               }

               // rook

               for (pos = 0; (inc=RookInc[pos]) != IncNone; pos++) {
                  for (to = from+inc; SQUARE_IS_OK(to); to += inc) {
                     if (DISTANCE(to,king) == 1) {
                        add_attack(2,king-from,to-from);
                        break;
                     }
                  }
               }

               // queen

               for (pos = 0; (inc=QueenInc[pos]) != IncNone; pos++) {
                  for (to = from+inc; SQUARE_IS_OK(to); to += inc) {
                     if (DISTANCE(to,king) == 1) {
                        add_attack(3,king-from,to-from);
                        break;
                     }
                  }
               }
            }
         }
      }
   }

   for (piece = 0; piece < 4; piece++) {
      for (delta = 0; delta < 256; delta++) {
         size = PieceDeltaSize[piece][delta];
         ASSERT(size>=0&&size<3);
         PieceDeltaDelta[piece][delta][size] = DeltaNone;
      }
   }
}