Ejemplo n.º 1
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.º 2
0
bool is_pinned(const board_t * board, int from, int to, int colour) {

    int king;
    int inc;
    int sq, piece;

    ASSERT(board!=NULL);
    ASSERT(square_is_ok(from));
    ASSERT(square_is_ok(to));
    ASSERT(colour_is_ok(colour));

    king = king_pos(board,colour);

    inc = DELTA_INC(king-from);
    if (inc == IncNone) return false; // not a line

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

    if (sq != king) return false; // blocker

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

    return square_is_ok(sq)
           && (piece & DELTA_MASK(king-sq)) != 0
           && piece_colour(piece) == colour_opp(colour)
           && DELTA_INC(king-to) != inc;
}
Ejemplo n.º 3
0
static void square_clear(board_t * board, int square, int piece) {

   int pos, piece_12, colour;
   int sq, size;

   ASSERT(board!=NULL);
   ASSERT(square_is_ok(square));
   ASSERT(piece_is_ok(piece));

   // init

   pos = board->pos[square];
   ASSERT(pos>=0);

   colour = piece_colour(piece);
   piece_12 = piece_to_12(piece);

   // square

   ASSERT(board->square[square]==piece);
   board->square[square] = Empty;

   ASSERT(board->pos[square]==pos);
   board->pos[square] = -1; // not needed

   // piece list

   ASSERT(board->variant==Horde?board->list_size[colour]>=1:board->list_size[colour]>=2);
   size = --board->list_size[colour];
   ASSERT(pos<=size);

   if (pos != size) {

      sq = board->list[colour][size];
      ASSERT(square_is_ok(sq));
      ASSERT(sq!=square);

      ASSERT(board->pos[sq]==size);
      board->pos[sq] = pos;

      ASSERT(board->list[colour][pos]==square);
      board->list[colour][pos] = sq;
   }

   board->list[colour][size] = SquareNone;

   // material

   ASSERT(board->number[piece_12]>=1);
   board->number[piece_12]--;

   // hash key

   board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square));
}
Ejemplo n.º 4
0
static void square_set(board_t * board, int square, int piece, int pos) {

   int piece_12, colour;
   int sq, size;

   ASSERT(board!=NULL);
   ASSERT(square_is_ok(square));
   ASSERT(piece_is_ok(piece));
   ASSERT(pos>=0);

   // init

   colour = piece_colour(piece);
   piece_12 = piece_to_12(piece);

   // square

   ASSERT(board->square[square]==Empty);
   board->square[square] = piece;

   ASSERT(board->pos[square]==-1);
   board->pos[square] = pos;

   // piece list

   size = board->list_size[colour]++;
   ASSERT(board->list[colour][size]==SquareNone);
   ASSERT(pos<=size);

   if (pos != size) {

      sq = board->list[colour][pos];
      ASSERT(square_is_ok(sq));
      ASSERT(sq!=square);

      ASSERT(board->pos[sq]==pos);
      board->pos[sq] = size;

      ASSERT(board->list[colour][size]==SquareNone);
      board->list[colour][size] = sq;
   }

   board->list[colour][pos] = square;

   // material

   ASSERT(board->number[piece_12]<=8);
   board->number[piece_12]++;

   // hash key

   board->key ^= random_64(RandomPiece+piece_12*64+square_to_64(square));
}
int History::move_ordering_score(Piece p, Square to) const {

  assert(piece_is_ok(p));
  assert(square_is_ok(to));

  return history[p][to];
}
Ejemplo n.º 6
0
static void square_move(board_t * board, int from, int to, int piece) {

   int colour, pos;
   int piece_index;

   ASSERT(board!=NULL);
   ASSERT(square_is_ok(from));
   ASSERT(square_is_ok(to));
   ASSERT(piece_is_ok(piece));

   // init

   colour = piece_colour(piece);

   pos = board->pos[from];
   ASSERT(pos>=0);

   // from

   ASSERT(board->square[from]==piece);
   board->square[from] = Empty;

   ASSERT(board->pos[from]==pos);
   board->pos[from] = -1; // not needed

   // to

   ASSERT(board->square[to]==Empty);
   board->square[to] = piece;

   ASSERT(board->pos[to]==-1);
   board->pos[to] = pos;

   // piece list

   ASSERT(board->list[colour][pos]==from);
   board->list[colour][pos] = to;

   // hash key

   piece_index = RandomPiece + piece_to_12(piece) * 64;

   board->key ^= random_64(piece_index+square_to_64(from))
               ^ random_64(piece_index+square_to_64(to));
}
void History::failure(Piece p, Square to, Depth d) {

  assert(piece_is_ok(p));
  assert(square_is_ok(to));

  history[p][to] -= int(d) * int(d);

  // Prevent history underflow
  if (history[p][to] <= -HistoryMax)
      for (int i = 0; i < 16; i++)
          for (int j = 0; j < 64; j++)
              history[i][j] /= 2;
}
void History::success(Piece p, Square to, Depth d) {

  assert(piece_is_ok(p));
  assert(square_is_ok(to));

  history[p][to] += int(d) * int(d);

  // Prevent history overflow
  if (history[p][to] >= HistoryMax)
      for (int i = 0; i < 16; i++)
          for (int j = 0; j < 64; j++)
              history[i][j] /= 2;
}
Ejemplo n.º 9
0
bool is_attacked(const board_t * board, int to, int colour) {

    const uint8 * ptr;
    int from, piece;

    ASSERT(board_is_ok(board));
    ASSERT(square_is_ok(to));
    ASSERT(colour_is_ok(colour));

    for (ptr = board->list[colour]; (from=*ptr) != SquareNone; ptr++) {

        piece = board->square[from];
        ASSERT(colour_equal(piece,colour));

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

    return false;
}
Ejemplo n.º 10
0
void init_direction_table() {
  SquareDelta deltas[8] = {
    DELTA_E, DELTA_W, DELTA_N, DELTA_S, DELTA_NE, DELTA_SW, DELTA_NW, DELTA_SE
  };
  for(Square s1 = SQ_A1; s1 <= SQ_H8; s1++)
    for(Square s2 = SQ_A1; s2 <= SQ_H8; s2++) {
      DirectionTable[s1][s2] = uint8_t(DIR_NONE);
      SignedDirectionTable[s1][s2] = uint8_t(SIGNED_DIR_NONE);
      if(s1 == s2) continue;
      for(SignedDirection d = SIGNED_DIR_E; d <= SIGNED_DIR_SE; d++) {
        SquareDelta delta = deltas[d];
        Square s3, s4;
        for(s4 = s1 + delta, s3 = s1;
            square_distance(s4, s3) == 1 && s4 != s2 && square_is_ok(s4);
            s3 = s4, s4 += delta);
        if(s4 == s2 && square_distance(s4, s3) == 1) {
          SignedDirectionTable[s1][s2] = uint8_t(d);
          DirectionTable[s1][s2] = uint8_t(d/2);
          break;
        }
      }
    }
}
Ejemplo n.º 11
0
bool board_is_ok(const board_t * board) {

   int sq, piece;
   int colour, pos;
   int king, rook;

   if (board == NULL) return false;

   // optional heavy DEBUG mode

   if (!UseSlowDebug) return true;

   // squares

   for (sq = 0; sq < SquareNb; sq++) {
      piece = board->square[sq];
      if (square_is_ok(sq)) {
         pos = board->pos[sq];
         if (piece == Empty) {
            if (pos != -1) return false;
         } else {
            if (pos < 0) return false;
            if (board->list[piece_colour(piece)][pos] != sq) return false;
         }
      } else {
         if (piece != Knight64) return false;
      }
   }

   // white piece list

   colour = White;
   pos = 0;

   if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return false;

   sq = board->list[colour][pos];
   if (sq == SquareNone) return false;
   if (board->pos[sq] != pos) return false;
   piece = board->square[sq];
   if (!colour_equal(piece,colour) || !piece_is_king(piece)) return false;

   for (pos++; pos < board->list_size[colour]; pos++) {
      sq = board->list[colour][pos];
      if (sq == SquareNone) return false;
      if (board->pos[sq] != pos) return false;
      if (!colour_equal(board->square[sq],colour)) return false;
   }

   sq = board->list[colour][pos];
   if (sq != SquareNone) return false;

   // black piece list

   colour = Black;
   pos = 0;

   if (board->list_size[colour] <= 0 || board->list_size[colour] > 16) return false;

   sq = board->list[colour][pos];
   if (sq == SquareNone) return false;
   if (board->pos[sq] != pos) return false;
   piece = board->square[sq];
   if (!colour_equal(piece,colour) || !piece_is_king(piece)) return false;

   for (pos++; pos < board->list_size[colour]; pos++) {
      sq = board->list[colour][pos];
      if (sq == SquareNone) return false;
      if (board->pos[sq] != pos) return false;
      if (!colour_equal(board->square[sq],colour)) return false;
   }

   sq = board->list[colour][pos];
   if (sq != SquareNone) return false;

   // TODO: material

   if (board->number[WhiteKing12] != 1) return false;
   if (board->number[BlackKing12] != 1) return false;

   if (!colour_is_ok(board->turn)) return false;

   // castling status

   if (board->castle[White][SideH] != SquareNone) {

      king = board->list[White][0];
      if (king < A1 || king > H1) return false;
      if (board->square[king] != WhiteKing256) return false;

      rook = board->castle[White][SideH];
      if (rook < A1 || rook > H1) return false;
      if (board->square[rook] != WhiteRook256) return false;

      if (rook <= king) return false;
   }

   if (board->castle[White][SideA] != SquareNone) {

      king = board->list[White][0];
      if (king < A1 || king > H1) return false;
      if (board->square[king] != WhiteKing256) return false;

      rook = board->castle[White][SideA];
      if (rook < A1 || rook > H1) return false;
      if (board->square[rook] != WhiteRook256) return false;

      if (rook >= king) return false;
   }

   if (board->castle[Black][SideH] != SquareNone) {

      king = board->list[Black][0];
      if (king < A8 || king > H8) return false;
      if (board->square[king] != BlackKing256) return false;

      rook = board->castle[Black][SideH];
      if (rook < A8 || rook > H8) return false;
      if (board->square[rook] != BlackRook256) return false;

      if (rook <= king) return false;
   }

   if (board->castle[Black][SideA] != SquareNone) {

      king = board->list[Black][0];
      if (king < A8 || king > H8) return false;
      if (board->square[king] != BlackKing256) return false;

      rook = board->castle[Black][SideA];
      if (rook < A8 || rook > H8) return false;
      if (board->square[rook] != BlackRook256) return false;

      if (rook >= king) return false;
   }

   return true;
}