Exemplo n.º 1
0
U64 hash_piece_key(S32 piece, S32 square) {

	ASSERT(piece_is_ok(piece));
	ASSERT(SQUARE_IS_OK(square));

	return RANDOM_64(RandomPiece + (PIECE_TO_12(piece) ^ 1) * 64 + SQUARE_TO_64(square)); // HACK: ^1 for PolyGlot book
}
Exemplo n.º 2
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;
}
int History::move_ordering_score(Piece p, Square to) const {

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

  return history[p][to];
}
Exemplo n.º 4
0
static void alists_hidden(alists_t * alists, const board_t * board, int from, int to) {

   int inc;
   int sq, piece;

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

   inc = DELTA_INC_LINE(to-from);

   if (inc != IncNone) { // line

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

      if (SLIDER_ATTACK(piece,inc)) {

         ASSERT(piece_is_ok(piece));
         ASSERT(PIECE_IS_SLIDER(piece));

         alist_add(alists->alist[PIECE_COLOUR(piece)],sq,board);
      }
   }
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
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));
}
Exemplo n.º 7
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));
}
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;
}
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;
}
Exemplo n.º 10
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));
}
Exemplo n.º 11
0
static int see_rec(alists_t * alists, const board_t * board, int colour, int to, int piece_value) {

   int from, piece;
   int value;

   ASSERT(alists!=NULL);
   ASSERT(board!=NULL);
   ASSERT(COLOUR_IS_OK(colour));
   ASSERT(SQUARE_IS_OK(to));
   ASSERT(piece_value>0);

   // find the least valuable attacker

   from = alist_pop(alists->alist[colour],board);
   if (from == SquareNone) return 0; // no more attackers

   // find hidden attackers

   alists_hidden(alists,board,from,to);

   // calculate the capture value

   value = +piece_value; // captured piece
   if (value == ValueKing) return value; // do not allow an answer to a king capture

   piece = board->square[from];
   ASSERT(piece_is_ok(piece));
   ASSERT(COLOUR_IS(piece,colour));
   piece_value = VALUE_PIECE(piece);

   // promote

   if (piece_value == ValuePawn && SQUARE_IS_PROMOTE(to)) { // HACK: PIECE_IS_PAWN(piece)
      ASSERT(PIECE_IS_PAWN(piece));
      piece_value = ValueQueen;
      value += ValueQueen - ValuePawn;
   }

   value -= see_rec(alists,board,COLOUR_OPP(colour),to,piece_value);

   if (value < 0) value = 0;

   return value;
}
Exemplo n.º 12
0
int see_square(const board_t * board, int to, int colour) {

   int att, def;
   alists_t alists[1];
   alist_t * alist;
   int piece_value;
   int piece;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(to));
   ASSERT(COLOUR_IS_OK(colour));

   ASSERT(COLOUR_IS(board->square[to],COLOUR_OPP(colour)));

   // build attacker list

   att = colour;
   alist = alists->alist[att];

   ALIST_CLEAR(alist);
   alist_build(alist,board,to,att);

   if (alist->size == 0) return 0; // no attacker => stop SEE

   // build defender list

   def = COLOUR_OPP(att);
   alist = alists->alist[def];

   ALIST_CLEAR(alist);
   alist_build(alist,board,to,def);

   // captured piece

   piece = board->square[to];
   ASSERT(piece_is_ok(piece));
   ASSERT(COLOUR_IS(piece,def));

   piece_value = VALUE_PIECE(piece);

   // SEE search

   return see_rec(alists,board,att,to,piece_value);
}
Exemplo n.º 13
0
bool piece_is_pawn(int piece) {

    ASSERT(piece_is_ok(piece));

    return (piece & PawnFlags) != 0;
}
Exemplo n.º 14
0
int piece_to_char(int piece) {

   ASSERT(piece_is_ok(piece));

   return PieceString[PIECE_TO_12(piece)];
}
Exemplo n.º 15
0
bool piece_is_knight(int piece) {

    ASSERT(piece_is_ok(piece));

    return (piece & KnightFlag) != 0;
}
Exemplo n.º 16
0
bool piece_is_rook(int piece) {

    ASSERT(piece_is_ok(piece));

    return (piece & QueenFlags) == RookFlag;
}
Exemplo n.º 17
0
bool piece_is_bishop(int piece) {

    ASSERT(piece_is_ok(piece));

    return (piece & QueenFlags) == BishopFlag;
}
Exemplo n.º 18
0
bool board_is_ok(const board_t * board) {

   int sq, piece, colour;
   int size, pos;

   if (board == NULL) return false;

   // optional heavy DEBUG mode

   if (!UseSlowDebug) return true;

   // squares

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

      piece = board->square[sq];
      pos = board->pos[sq];

      if (SQUARE_IS_OK(sq)) {

         // inside square

         if (piece == Empty) {

            if (pos != -1) return false;

         } else {

            if (!piece_is_ok(piece)) return false;

            if (!PIECE_IS_PAWN(piece)) {

               colour = PIECE_COLOUR(piece);
               if (pos < 0 || pos >= board->piece_size[colour]) return false;
               if (board->piece[colour][pos] != sq) return false;

            } else { // pawn

               if (SQUARE_IS_PROMOTE(sq)) return false;

               colour = PIECE_COLOUR(piece);
               if (pos < 0 || pos >= board->pawn_size[colour]) return false;
               if (board->pawn[colour][pos] != sq) return false;
            }
         }

      } else {

         // edge square

         if (piece != Edge) return false;
         if (pos != -1) return false;
      }
   }

   // piece lists

   for (colour = 0; colour < ColourNb; colour++) {

      // piece list

      size = board->piece_size[colour];
      if (size < 1 || size > 16) return false;

      for (pos = 0; pos < size; pos++) {

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

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

         piece = board->square[sq];
         if (!COLOUR_IS(piece,colour)) return false;
         if (pos == 0 && !PIECE_IS_KING(piece)) return false;
         if (pos != 0 && PIECE_IS_KING(piece)) return false;

         if (pos != 0 && PIECE_ORDER(piece) > PIECE_ORDER(board->square[board->piece[colour][pos-1]])) {
            return false;
         }
      }

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

      // pawn list

      size = board->pawn_size[colour];
      if (size < 0 || size > 8) return false;

      for (pos = 0; pos < size; pos++) {

         sq = board->pawn[colour][pos];
         if (!SQUARE_IS_OK(sq)) return false;
         if (SQUARE_IS_PROMOTE(sq)) return false;

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

         piece = board->square[sq];
         if (!COLOUR_IS(piece,colour)) return false;
         if (!PIECE_IS_PAWN(piece)) return false;
      }

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

      // piece total

      if (board->piece_size[colour] + board->pawn_size[colour] > 16) return false;
   }

   // material

   if (board->piece_nb != board->piece_size[White] + board->pawn_size[White]
                        + board->piece_size[Black] + board->pawn_size[Black]) {
      return false;
   }

   if (board->number[WhitePawn12] != board->pawn_size[White]) return false;
   if (board->number[BlackPawn12] != board->pawn_size[Black]) return false;
   if (board->number[WhiteKing12] != 1) return false;
   if (board->number[BlackKing12] != 1) return false;

   // misc

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

   if (board->ply_nb < 0) return false;
   if (board->sp < board->ply_nb) return false;

   if (board->cap_sq != SquareNone && !SQUARE_IS_OK(board->cap_sq)) return false;

   if (board->opening != board_opening(board)) return false;
   if (board->endgame != board_endgame(board)) return false;
   if (board->key != hash_key(board)) return false;
   if (board->pawn_key != hash_pawn_key(board)) return false;
   if (board->material_key != hash_material_key(board)) return false;

   return true;
}
Exemplo n.º 19
0
bool piece_is_queen(int piece) {

    ASSERT(piece_is_ok(piece));

    return (piece & QueenFlags) == QueenFlags;
}
Exemplo n.º 20
0
static void square_move(board_t * board, int from, int to, int piece, bool update) {

   int colour;
   int pos;
   int from_64, to_64;
   int piece_12;
   int piece_index;
   uint64 hash_xor;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(from));
   ASSERT(SQUARE_IS_OK(to));
   ASSERT(piece_is_ok(piece));
   ASSERT(update==true||update==false);

   // 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

   if (!PIECE_IS_PAWN(piece)) {

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

   } else {

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

      // pawn "bitboard"

      board->pawn_file[colour][SQUARE_FILE(from)] ^= BIT(PAWN_RANK(from,colour));
      board->pawn_file[colour][SQUARE_FILE(to)]   ^= BIT(PAWN_RANK(to,colour));
   }

   // update

   if (update) {

      // init

      from_64 = SQUARE_TO_64(from);
      to_64 = SQUARE_TO_64(to);
      piece_12 = PIECE_TO_12(piece);

      // PST

      board->opening += PST(piece_12,to_64,Opening) - PST(piece_12,from_64,Opening);
      board->endgame += PST(piece_12,to_64,Endgame) - PST(piece_12,from_64,Endgame);

      // hash key

      piece_index = RandomPiece + (piece_12^1) * 64; // HACK: ^1 for PolyGlot book

      hash_xor = RANDOM_64(piece_index+to_64) ^ RANDOM_64(piece_index+from_64);

      board->key ^= hash_xor;
      if (PIECE_IS_PAWN(piece)) board->pawn_key ^= hash_xor;
   }
}
Exemplo n.º 21
0
void board_init_list(board_t * board) {

   int sq_64, sq, piece;
   int colour, pos;
   int i, size;
   int square;
   int order;
   int file;

   ASSERT(board!=NULL);

   // init

   for (sq = 0; sq < SquareNb; sq++) {
      board->pos[sq] = -1;
   }

   board->piece_nb = 0;
   for (piece = 0; piece < 12; piece++) board->number[piece] = 0;

   // piece lists

   for (colour = 0; colour < ColourNb; colour++) {

      // piece list

      pos = 0;

      for (sq_64 = 0; sq_64 < 64; sq_64++) {

         sq = SQUARE_FROM_64(sq_64);
         piece = board->square[sq];
         if (piece != Empty && !piece_is_ok(piece)) my_fatal("board_init_list(): illegal position\n");

         if (COLOUR_IS(piece,colour) && !PIECE_IS_PAWN(piece)) {

            if (pos >= 16) my_fatal("board_init_list(): illegal position\n");
            ASSERT(pos>=0&&pos<16);

            board->pos[sq] = pos;
            board->piece[colour][pos] = sq;
            pos++;

            board->piece_nb++;
            board->number[PIECE_TO_12(piece)]++;
         }
      }

      if (board->number[COLOUR_IS_WHITE(colour)?WhiteKing12:BlackKing12] != 1) my_fatal("board_init_list(): illegal position\n");

      ASSERT(pos>=1&&pos<=16);
      board->piece[colour][pos] = SquareNone;
      board->piece_size[colour] = pos;

      // MV sort

      size = board->piece_size[colour];

      for (i = 1; i < size; i++) {

         square = board->piece[colour][i];
         piece = board->square[square];
         order = PIECE_ORDER(piece);

         for (pos = i; pos > 0 && order > PIECE_ORDER(board->square[(sq=board->piece[colour][pos-1])]); pos--) {
            ASSERT(pos>0&&pos<size);
            board->piece[colour][pos] = sq;
            ASSERT(board->pos[sq]==pos-1);
            board->pos[sq] = pos;
         }

         ASSERT(pos>=0&&pos<size);
         board->piece[colour][pos] = square;
         ASSERT(board->pos[square]==i);
         board->pos[square] = pos;
      }

      // debug

      if (DEBUG) {

         for (i = 0; i < board->piece_size[colour]; i++) {

            sq = board->piece[colour][i];
            ASSERT(board->pos[sq]==i);

            if (i == 0) { // king
               ASSERT(PIECE_IS_KING(board->square[sq]));
            } else {
               ASSERT(!PIECE_IS_KING(board->square[sq]));
               ASSERT(PIECE_ORDER(board->square[board->piece[colour][i]])<=PIECE_ORDER(board->square[board->piece[colour][i-1]]));
            }
         }
      }

      // pawn list

      for (file = 0; file < FileNb; file++) {
         board->pawn_file[colour][file] = 0;
      }

      pos = 0;

      for (sq_64 = 0; sq_64 < 64; sq_64++) {

         sq = SQUARE_FROM_64(sq_64);
         piece = board->square[sq];

         if (COLOUR_IS(piece,colour) && PIECE_IS_PAWN(piece)) {

            if (pos >= 8 || SQUARE_IS_PROMOTE(sq)) my_fatal("board_init_list(): illegal position\n");
            ASSERT(pos>=0&&pos<8);

            board->pos[sq] = pos;
            board->pawn[colour][pos] = sq;
            pos++;

            board->piece_nb++;
            board->number[PIECE_TO_12(piece)]++;
            board->pawn_file[colour][SQUARE_FILE(sq)] |= BIT(PAWN_RANK(sq,colour));
         }
      }

      ASSERT(pos>=0&&pos<=8);
      board->pawn[colour][pos] = SquareNone;
      board->pawn_size[colour] = pos;

      if (board->piece_size[colour] + board->pawn_size[colour] > 16) my_fatal("board_init_list(): illegal position\n");
   }

   // last square

   board->cap_sq = SquareNone;

   // PST

   board->opening = board_opening(board);
   board->endgame = board_endgame(board);

   // hash key

   for (i = 0; i < board->ply_nb; i++) board->stack[i] = 0; // HACK
   board->sp = board->ply_nb;

   board->key = hash_key(board);
   board->pawn_key = hash_pawn_key(board);
   board->material_key = hash_material_key(board);

   // legality

   if (!board_is_legal(board)) my_fatal("board_init_list(): illegal position\n");

   // debug

   ASSERT(board_is_ok(board));
}
Exemplo n.º 22
0
bool piece_is_king(int piece) {

    ASSERT(piece_is_ok(piece));

    return (piece & KingFlag) != 0;
}
Exemplo n.º 23
0
bool piece_is_slider(int piece) {

    ASSERT(piece_is_ok(piece));

    return (piece & QueenFlags) != 0;
}
Exemplo n.º 24
0
int piece_to_12(int piece) {

    ASSERT(piece_is_ok(piece));

    return PieceTo12[piece];
}
Exemplo n.º 25
0
int piece_type(int piece) {

    ASSERT(piece_is_ok(piece));

    return piece & ~3;
}
Exemplo n.º 26
0
int piece_colour(int piece) {

    ASSERT(piece_is_ok(piece));

    return piece & 3;
}
Exemplo n.º 27
0
int see_move(int move, const board_t * board) {

   int att, def;
   int from, to;
   alists_t alists[1];
   int value, piece_value;
   int piece, capture;
   alist_t * alist;
   int pos;

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

   // init

   from = MOVE_FROM(move);
   to = MOVE_TO(move);

   // move the piece

   piece_value = 0;

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

   att = PIECE_COLOUR(piece);
   def = COLOUR_OPP(att);

   // promote

   if (MOVE_IS_PROMOTE(move)) {
      ASSERT(PIECE_IS_PAWN(piece));
      piece = move_promote(move);
      ASSERT(piece_is_ok(piece));
      ASSERT(COLOUR_IS(piece,att));
   }

   piece_value += VALUE_PIECE(piece);

   // clear attacker lists

   ALIST_CLEAR(alists->alist[Black]);
   ALIST_CLEAR(alists->alist[White]);

   // find hidden attackers

   alists_hidden(alists,board,from,to);

   // capture the piece

   value = 0;

   capture = board->square[to];

   if (capture != Empty) {

      ASSERT(piece_is_ok(capture));
      ASSERT(COLOUR_IS(capture,def));

      value += VALUE_PIECE(capture);
   }

   // promote

   if (MOVE_IS_PROMOTE(move)) {
      value += VALUE_PIECE(piece) - ValuePawn;
   }

   // en-passant

   if (MOVE_IS_EN_PASSANT(move)) {
      ASSERT(value==0);
      ASSERT(PIECE_IS_PAWN(board->square[SQUARE_EP_DUAL(to)]));
      value += ValuePawn;
      alists_hidden(alists,board,SQUARE_EP_DUAL(to),to);
   }

   // build defender list

   alist = alists->alist[def];

   alist_build(alist,board,to,def);
   if (alist->size == 0) return value; // no defender => stop SEE

   // build attacker list

   alist = alists->alist[att];

   alist_build(alist,board,to,att);

   // remove the moved piece (if it's an attacker)

   for (pos = 0; pos < alist->size && alist->square[pos] != from; pos++)
      ;

   if (pos < alist->size) alist_remove(alist,pos);

   // SEE search

   value -= see_rec(alists,board,def,to,piece_value);

   return value;
}
Exemplo n.º 28
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;
}
Exemplo n.º 29
0
bool board_to_fen(const board_t * board, char fen[], int size) {

   int pos;
   int file, rank;
   int sq, piece;
   int c;
   int len;

   ASSERT(board!=NULL);
   ASSERT(fen!=NULL);
   ASSERT(size>=92);

   // init

   if (size < 92) return false;

   pos = 0;

   // piece placement

   for (rank = Rank8; rank >= Rank1; rank--) {

      for (file = FileA; file <= FileH;) {

         sq = SQUARE_MAKE(file,rank);
         piece = board->square[sq];
         ASSERT(piece==Empty||piece_is_ok(piece));

         if (piece == Empty) {

            len = 0;
            for (; file <= FileH && board->square[SQUARE_MAKE(file,rank)] == Empty; file++) {
               len++;
            }

            ASSERT(len>=1&&len<=8);
            c = '0' + len;

         } else {

            c = piece_to_char(piece);
            file++;
         }

         fen[pos++] = c;
      }

      fen[pos++] = '/';
   }

   fen[pos-1] = ' '; // HACK: remove the last '/'

   // active colour

   fen[pos++] = (COLOUR_IS_WHITE(board->turn)) ? 'w' : 'b';
   fen[pos++] = ' ';

   // castling

   if (board->flags == FlagsNone) {
      fen[pos++] = '-';
   } else {
      if ((board->flags & FlagsWhiteKingCastle)  != 0) fen[pos++] = 'K';
      if ((board->flags & FlagsWhiteQueenCastle) != 0) fen[pos++] = 'Q';
      if ((board->flags & FlagsBlackKingCastle)  != 0) fen[pos++] = 'k';
      if ((board->flags & FlagsBlackQueenCastle) != 0) fen[pos++] = 'q';
   }

   fen[pos++] = ' ';

   // en-passant

   if (board->ep_square == SquareNone) {
      fen[pos++] = '-';
   } else {
      square_to_string(board->ep_square,&fen[pos],3);
      pos += 2;
   }

   fen[pos++] = ' ';

   // halfmove clock

   sprintf(&fen[pos],"%d 1",board->ply_nb);

   return true;
}
Exemplo n.º 30
0
static void square_set(board_t * board, int square, int piece, int pos, bool update) {

   int piece_12, colour;
   int sq;
   int i, size;
   int sq_64;
   uint64 hash_xor;

   ASSERT(board!=NULL);
   ASSERT(SQUARE_IS_OK(square));
   ASSERT(piece_is_ok(piece));
   ASSERT(pos>=0);
   ASSERT(update==true||update==false);

   // init

   piece_12 = PIECE_TO_12(piece);
   colour = PIECE_COLOUR(piece);

   // square

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

   // piece list

   if (!PIECE_IS_PAWN(piece)) {

      // init

      size = board->piece_size[colour];
      ASSERT(size>=0);

      // size

      size++;

      board->piece[colour][size] = SquareNone;
      board->piece_size[colour] = size;

      // stable swap

      ASSERT(pos>=0&&pos<size);

      for (i = size-1; i > pos; i--) {

         sq = board->piece[colour][i-1];

         board->piece[colour][i] = sq;

         ASSERT(board->pos[sq]==i-1);
         board->pos[sq] = i;
      }

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

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

   } else {

      // init

      size = board->pawn_size[colour];
      ASSERT(size>=0);

      // size

      size++;

      board->pawn[colour][size] = SquareNone;
      board->pawn_size[colour] = size;

      // stable swap

      ASSERT(pos>=0&&pos<size);

      for (i = size-1; i > pos; i--) {

         sq = board->pawn[colour][i-1];

         board->pawn[colour][i] = sq;

         ASSERT(board->pos[sq]==i-1);
         board->pos[sq] = i;
      }

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

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

      // pawn "bitboard"

      board->pawn_file[colour][SQUARE_FILE(square)] ^= BIT(PAWN_RANK(square,colour));
   }

   // material

   ASSERT(board->piece_nb<32);
   board->piece_nb++;;

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

   // update

   if (update) {

      // init

      sq_64 = SQUARE_TO_64(square);

      // PST

      board->opening += PST(piece_12,sq_64,Opening);
      board->endgame += PST(piece_12,sq_64,Endgame);

      // hash key

      hash_xor = RANDOM_64(RandomPiece+(piece_12^1)*64+sq_64); // HACK: ^1 for PolyGlot book

      board->key ^= hash_xor;
      if (PIECE_IS_PAWN(piece)) board->pawn_key ^= hash_xor;

      // material key

      board->material_key ^= RANDOM_64(piece_12*16+(board->number[piece_12]-1));
   }
}