]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Fix a bug in Position::is_ok()
[stockfish] / src / position.cpp
index c4d056201bcbecdd5430d68086ca6f709d053e1e..42fdd62da8bfc3c121c61916164449682a2ed630 100644 (file)
@@ -366,7 +366,7 @@ void Position::print(Move move) const {
   if (move)
   {
       Position p(*this, thread());
-      string dd = (color_of_piece(piece_on(move_from(move))) == BLACK ? ".." : "");
+      string dd = (piece_color(piece_on(move_from(move))) == BLACK ? ".." : "");
       cout << "\nMove is: " << dd << move_to_san(p, move);
   }
 
@@ -381,7 +381,7 @@ void Position::print(Move move) const {
           if (piece == PIECE_NONE && square_color(sq) == DARK)
               piece = PIECE_NONE_DARK_SQ;
 
-          char c = (color_of_piece(piece_on(sq)) == BLACK ? '=' : ' ');
+          char c = (piece_color(piece_on(sq)) == BLACK ? '=' : ' ');
           cout << c << PieceToChar[piece] << c << '|';
       }
   }
@@ -520,7 +520,7 @@ bool Position::move_attacks_square(Move m, Square s) const {
   do_move_bb(&occ, make_move_bb(f, t));
   xray = ( (rook_attacks_bb(s, occ)   & pieces(ROOK, QUEEN))
           |(bishop_attacks_bb(s, occ) & pieces(BISHOP, QUEEN)))
-         & pieces_of_color(color_of_piece(piece_on(f)));
+         & pieces_of_color(piece_color(piece_on(f)));
 
   // If we have attacks we need to verify that are caused by our move
   // and are not already existent ones.
@@ -552,7 +552,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
   Color us = side_to_move();
   Square from = move_from(m);
 
-  assert(color_of_piece(piece_on(from)) == us);
+  assert(piece_color(piece_on(from)) == us);
   assert(piece_on(king_square(us)) == make_piece(us, KING));
 
   // En passant captures are a tricky special case. Because they are
@@ -582,7 +582,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
   // If the moving piece is a king, check whether the destination
   // square is attacked by the opponent. Castling moves are checked
   // for legality during move generation.
-  if (type_of_piece(piece_on(from)) == KING)
+  if (piece_type(piece_on(from)) == KING)
       return move_is_castle(m) || !(attackers_to(move_to(m)) & pieces_of_color(opposite_color(us)));
 
   // A non-king move is legal if and only if it is not pinned or it
@@ -636,15 +636,15 @@ bool Position::move_is_pl(const Move m) const {
 
   // If the from square is not occupied by a piece belonging to the side to
   // move, the move is obviously not legal.
-  if (pc == PIECE_NONE || color_of_piece(pc) != us)
+  if (pc == PIECE_NONE || piece_color(pc) != us)
       return false;
 
   // The destination square cannot be occupied by a friendly piece
-  if (color_of_piece(piece_on(to)) == us)
+  if (piece_color(piece_on(to)) == us)
       return false;
 
   // Handle the special case of a pawn move
-  if (type_of_piece(pc) == PAWN)
+  if (piece_type(pc) == PAWN)
   {
       // Move direction must be compatible with pawn color
       int direction = to - from;
@@ -666,7 +666,7 @@ bool Position::move_is_pl(const Move m) const {
       case DELTA_SE:
       // Capture. The destination square must be occupied by an enemy
       // piece (en passant captures was handled earlier).
-      if (color_of_piece(piece_on(to)) != them)
+      if (piece_color(piece_on(to)) != them)
           return false;
 
       // From and to files must be one file apart, avoids a7h5
@@ -712,7 +712,7 @@ bool Position::move_is_pl(const Move m) const {
   {
       // In case of king moves under check we have to remove king so to catch
       // as invalid moves like b1a1 when opposite queen is on c1.
-      if (type_of_piece(piece_on(from)) == KING)
+      if (piece_type(piece_on(from)) == KING)
       {
           Bitboard b = occupied_squares();
           clear_bit(&b, from);
@@ -745,11 +745,11 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
   assert(is_ok());
   assert(move_is_ok(m));
   assert(ci.dcCandidates == discovered_check_candidates(side_to_move()));
-  assert(color_of_piece(piece_on(move_from(m))) == side_to_move());
+  assert(piece_color(piece_on(move_from(m))) == side_to_move());
 
   Square from = move_from(m);
   Square to = move_to(m);
-  PieceType pt = type_of_piece(piece_on(from));
+  PieceType pt = piece_type(piece_on(from));
 
   // Direct check ?
   if (bit_is_set(ci.checkSq[pt], to))
@@ -917,11 +917,11 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
   bool pm = move_is_promotion(m);
 
   Piece piece = piece_on(from);
-  PieceType pt = type_of_piece(piece);
-  PieceType capture = ep ? PAWN : type_of_piece(piece_on(to));
+  PieceType pt = piece_type(piece);
+  PieceType capture = ep ? PAWN : piece_type(piece_on(to));
 
-  assert(color_of_piece(piece_on(from)) == us);
-  assert(color_of_piece(piece_on(to)) == them || square_is_empty(to));
+  assert(piece_color(piece_on(from)) == us);
+  assert(piece_color(piece_on(to)) == them || square_is_empty(to));
   assert(!(ep || pm) || piece == make_piece(us, PAWN));
   assert(!pm || relative_rank(us, to) == RANK_8);
 
@@ -1255,10 +1255,10 @@ void Position::undo_move(Move m) {
   bool ep = move_is_ep(m);
   bool pm = move_is_promotion(m);
 
-  PieceType pt = type_of_piece(piece_on(to));
+  PieceType pt = piece_type(piece_on(to));
 
   assert(square_is_empty(from));
-  assert(color_of_piece(piece_on(to)) == us);
+  assert(piece_color(piece_on(to)) == us);
   assert(!pm || relative_rank(us, to) == RANK_8);
   assert(!ep || to == st->previous->epSquare);
   assert(!ep || relative_rank(us, to) == RANK_6);
@@ -1502,16 +1502,16 @@ int Position::see(Move m) const {
 
   from = move_from(m);
   to = move_to(m);
-  capturedType = type_of_piece(piece_on(to));
+  capturedType = piece_type(piece_on(to));
   occupied = occupied_squares();
 
   // Handle en passant moves
-  if (st->epSquare == to && type_of_piece(piece_on(from)) == PAWN)
+  if (st->epSquare == to && piece_type(piece_on(from)) == PAWN)
   {
       Square capQq = (side_to_move() == WHITE ? to - DELTA_N : to - DELTA_S);
 
       assert(capturedType == PIECE_TYPE_NONE);
-      assert(type_of_piece(piece_on(capQq)) == PAWN);
+      assert(piece_type(piece_on(capQq)) == PAWN);
 
       // Remove the captured pawn
       clear_bit(&occupied, capQq);
@@ -1524,7 +1524,7 @@ int Position::see(Move m) const {
   attackers = attackers_to(to, occupied);
 
   // If the opponent has no attackers we are finished
-  stm = opposite_color(color_of_piece(piece_on(from)));
+  stm = opposite_color(piece_color(piece_on(from)));
   stmAttackers = attackers & pieces_of_color(stm);
   if (!stmAttackers)
       return PieceValueMidgame[capturedType];
@@ -1536,7 +1536,7 @@ int Position::see(Move m) const {
   // capture with the least valuable piece. After each capture, we look for
   // new X-ray attacks from behind the capturing piece.
   swapList[0] = PieceValueMidgame[capturedType];
-  capturedType = type_of_piece(piece_on(from));
+  capturedType = piece_type(piece_on(from));
 
   do {
       // Locate the least valuable attacker for the side to move. The loop
@@ -1621,8 +1621,8 @@ void Position::clear() {
 
 void Position::put_piece(Piece p, Square s) {
 
-  Color c = color_of_piece(p);
-  PieceType pt = type_of_piece(p);
+  Color c = piece_color(p);
+  PieceType pt = piece_type(p);
 
   board[s] = p;
   index[s] = pieceCount[c][pt]++;
@@ -1645,7 +1645,7 @@ Key Position::compute_key() const {
 
   for (Square s = SQ_A1; s <= SQ_H8; s++)
       if (square_is_occupied(s))
-          result ^= zobrist[color_of_piece(piece_on(s))][type_of_piece(piece_on(s))][s];
+          result ^= zobrist[piece_color(piece_on(s))][piece_type(piece_on(s))][s];
 
   if (ep_square() != SQ_NONE)
       result ^= zobEp[ep_square()];
@@ -1923,8 +1923,8 @@ bool Position::is_ok(int* failedStep) const {
   {
       int kingCount[2] = {0, 0};
       for (Square s = SQ_A1; s <= SQ_H8; s++)
-          if (type_of_piece(piece_on(s)) == KING)
-              kingCount[color_of_piece(piece_on(s))]++;
+          if (piece_type(piece_on(s)) == KING)
+              kingCount[piece_color(piece_on(s))]++;
 
       if (kingCount[0] != 1 || kingCount[1] != 1)
           return false;
@@ -2039,14 +2039,19 @@ bool Position::is_ok(int* failedStep) const {
           if (can_castle_queenside(c) && piece_on(initial_qr_square(c)) != make_piece(c, ROOK))
               return false;
       }
-      if (castleRightsMask[initial_kr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OO))
-          return false;
-      if (castleRightsMask[initial_qr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OOO))
-          return false;
-      if (castleRightsMask[initial_kr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OO))
-          return false;
-      if (castleRightsMask[initial_qr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OOO))
-          return false;
+      // If we cannot castle castleRightsMask[] could be not valid, for instance when
+      // king initial file is FILE_A as queen rook.
+      if (can_castle(WHITE) || can_castle(BLACK))
+      {
+          if (castleRightsMask[initial_kr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OO))
+              return false;
+          if (castleRightsMask[initial_qr_square(WHITE)] != (ALL_CASTLES ^ WHITE_OOO))
+              return false;
+          if (castleRightsMask[initial_kr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OO))
+              return false;
+          if (castleRightsMask[initial_qr_square(BLACK)] != (ALL_CASTLES ^ BLACK_OOO))
+              return false;
+      }
   }
 
   if (failedStep) *failedStep = 0;