]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Use #ifndef instead of #if !defined
[stockfish] / src / position.cpp
index 1273a62fb3d0a0e975e2d06cdbf590359d9c473d..f7a89e07f3d88afacdf7f6ae18b80a706834d77e 100644 (file)
@@ -59,32 +59,32 @@ Key Position::exclusion_key() const { return st->key ^ Zobrist::exclusion;}
 
 namespace {
 
-// next_attacker() is an helper function used by see() to locate the least
+// min_attacker() is an helper function used by see() to locate the least
 // valuable attacker for the side to move, remove the attacker we just found
-// from the 'occupied' bitboard and scan for new X-ray attacks behind it.
+// from the bitboards and scan for new X-ray attacks behind it.
 
 template<int Pt> FORCE_INLINE
-PieceType next_attacker(const Bitboard* bb, const Square& to, const Bitboard& stmAttackers,
-                        Bitboard& occupied, Bitboard& attackers) {
+PieceType min_attacker(const Bitboard* bb, const Square& to, const Bitboard& stmAttackers,
+                       Bitboard& occupied, Bitboard& attackers) {
 
-  if (stmAttackers & bb[Pt])
-  {
-      Bitboard b = stmAttackers & bb[Pt];
-      occupied ^= b & ~(b - 1);
+  Bitboard b = stmAttackers & bb[Pt];
+  if (!b)
+      return min_attacker<Pt+1>(bb, to, stmAttackers, occupied, attackers);
 
-      if (Pt == PAWN || Pt == BISHOP || Pt == QUEEN)
-          attackers |= attacks_bb<BISHOP>(to, occupied) & (bb[BISHOP] | bb[QUEEN]);
+  occupied ^= b & ~(b - 1);
 
-      if (Pt == ROOK || Pt == QUEEN)
-          attackers |= attacks_bb<ROOK>(to, occupied) & (bb[ROOK] | bb[QUEEN]);
+  if (Pt == PAWN || Pt == BISHOP || Pt == QUEEN)
+      attackers |= attacks_bb<BISHOP>(to, occupied) & (bb[BISHOP] | bb[QUEEN]);
 
-      return (PieceType)Pt;
-  }
-  return next_attacker<Pt+1>(bb, to, stmAttackers, occupied, attackers);
+  if (Pt == ROOK || Pt == QUEEN)
+      attackers |= attacks_bb<ROOK>(to, occupied) & (bb[ROOK] | bb[QUEEN]);
+
+  attackers &= occupied; // After X-ray that may add already processed pieces
+  return (PieceType)Pt;
 }
 
 template<> FORCE_INLINE
-PieceType next_attacker<KING>(const Bitboard*, const Square&, const Bitboard&, Bitboard&, Bitboard&) {
+PieceType min_attacker<KING>(const Bitboard*, const Square&, const Bitboard&, Bitboard&, Bitboard&) {
   return KING; // No need to update bitboards, it is the last cycle
 }
 
@@ -542,7 +542,7 @@ bool Position::is_pseudo_legal(const Move m) const {
       return false;
 
   // The destination square cannot be occupied by a friendly piece
-  if (piece_on(to) != NO_PIECE && color_of(piece_on(to)) == us)
+  if (pieces(us) & to)
       return false;
 
   // Handle the special case of a pawn move
@@ -690,9 +690,9 @@ bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
       Square rfrom = to; // 'King captures the rook' notation
       Square kto = relative_square(us, rfrom > kfrom ? SQ_G1 : SQ_C1);
       Square rto = relative_square(us, rfrom > kfrom ? SQ_F1 : SQ_D1);
-      Bitboard b = (pieces() ^ kfrom ^ rfrom) | rto | kto;
 
-      return attacks_bb<ROOK>(rto, b) & ksq;
+      return   (PseudoAttacks[ROOK][rto] & ksq)
+            && (attacks_bb<ROOK>(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & ksq);
   }
   default:
       assert(false);
@@ -1133,7 +1133,7 @@ int Position::see_sign(Move m) const {
   // Early return if SEE cannot be negative because captured piece value
   // is not less then capturing one. Note that king moves always return
   // here because king midgame value is set to 0.
-  if (PieceValue[MG][piece_on(to_sq(m))] >= PieceValue[MG][piece_moved(m)])
+  if (PieceValue[MG][piece_moved(m)] <= PieceValue[MG][piece_on(to_sq(m))])
       return 1;
 
   return see(m);
@@ -1151,36 +1151,31 @@ int Position::see(Move m, int asymmThreshold) const {
 
   from = from_sq(m);
   to = to_sq(m);
-  captured = type_of(piece_on(to));
+  swapList[0] = PieceValue[MG][type_of(piece_on(to))];
+  stm = color_of(piece_on(from));
   occupied = pieces() ^ from;
 
-  // Handle en passant moves
+  // Castle moves are implemented as king capturing the rook so cannot be
+  // handled correctly. Simply return 0 that is always the correct value
+  // unless in the rare case the rook ends up under attack.
+  if (type_of(m) == CASTLE)
+      return 0;
+
   if (type_of(m) == ENPASSANT)
   {
-      Square capQq = to - pawn_push(sideToMove);
-
-      assert(!captured);
-      assert(type_of(piece_on(capQq)) == PAWN);
-
-      // Remove the captured pawn
-      occupied ^= capQq;
-      captured = PAWN;
+      occupied ^= to - pawn_push(stm); // Remove the captured pawn
+      swapList[0] = PieceValue[MG][PAWN];
   }
-  else if (type_of(m) == CASTLE)
-      // Castle moves are implemented as king capturing the rook so cannot be
-      // handled correctly. Simply return 0 that is always the correct value
-      // unless the rook is ends up under attack.
-      return 0;
 
   // Find all attackers to the destination square, with the moving piece
   // removed, but possibly an X-ray attacker added behind it.
-  attackers = attackers_to(to, occupied);
+  attackers = attackers_to(to, occupied) & occupied;
 
   // If the opponent has no attackers we are finished
-  stm = ~color_of(piece_on(from));
+  stm = ~stm;
   stmAttackers = attackers & pieces(stm);
   if (!stmAttackers)
-      return PieceValue[MG][captured];
+      return swapList[0];
 
   // The destination square is defended, which makes things rather more
   // difficult to compute. We proceed by building up a "swap list" containing
@@ -1188,7 +1183,6 @@ int Position::see(Move m, int asymmThreshold) const {
   // destination square, where the sides alternately capture, and always
   // capture with the least valuable piece. After each capture, we look for
   // new X-ray attacks from behind the capturing piece.
-  swapList[0] = PieceValue[MG][captured];
   captured = type_of(piece_on(from));
 
   do {
@@ -1198,19 +1192,15 @@ int Position::see(Move m, int asymmThreshold) const {
       swapList[slIndex] = -swapList[slIndex - 1] + PieceValue[MG][captured];
       slIndex++;
 
-      // Locate and remove from 'occupied' the next least valuable attacker
-      captured = next_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
-
-      attackers &= occupied; // Remove the just found attacker
+      // Locate and remove the next least valuable attacker
+      captured = min_attacker<PAWN>(byTypeBB, to, stmAttackers, occupied, attackers);
       stm = ~stm;
       stmAttackers = attackers & pieces(stm);
 
-      if (captured == KING)
+      // Stop before processing a king capture
+      if (captured == KING && stmAttackers)
       {
-          // Stop before processing a king capture
-          if (stmAttackers)
-              swapList[slIndex++] = QueenValueMg * 16;
-
+          swapList[slIndex++] = QueenValueMg * 16;
           break;
       }