Super fast hidden_checkers()
authorMarco Costalba <mcostalba@gmail.com>
Wed, 4 Mar 2009 11:04:28 +0000 (12:04 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Wed, 4 Mar 2009 21:50:51 +0000 (22:50 +0100)
Rewritten hidden_checkers() to avoid calling
sliders attacks functions but just a much
faster squares_between()

Also a good code semplification.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
src/position.cpp
src/position.h

index fc9e23c91a9342d635d33e9c7a18da0215742cf6..21839d6abaf32e52e48d027e4a9b626864496fc3 100644 (file)
@@ -320,71 +320,40 @@ void Position::copy(const Position &pos) {
 }
 
 
 }
 
 
-/// Position:pinned_pieces() returns a bitboard of all pinned (against the
-/// king) pieces for the given color.
-Bitboard Position::pinned_pieces(Color c) const {
-
-  Bitboard p;
-  Square ksq = king_square(c);
-  return hidden_checks<ROOK, true>(c, ksq, p) | hidden_checks<BISHOP, true>(c, ksq, p);
-}
-
+/// Position:hidden_checkers<>() returns a bitboard of all pinned (against the
+/// king) pieces for the given color and for the given pinner type. Or, when
+/// template parameter FindPinned is false, the pieces of the given color
+/// candidate for a discovery check against the enemy king.
+/// Note that checkersBB bitboard must be already updated.
 
 
-/// Position:discovered_check_candidates() returns a bitboard containing all
-/// pieces for the given side which are candidates for giving a discovered
-/// check.  The code is almost the same as the function for finding pinned
-/// pieces.
+template<bool FindPinned>
+Bitboard Position::hidden_checkers(Color c) const {
 
 
-Bitboard Position::discovered_check_candidates(Color c) const {
+  Bitboard pinners, result = EmptyBoardBB;
 
 
-  Bitboard p;
-  Square ksq = king_square(opposite_color(c));
-  return hidden_checks<ROOK, false>(c, ksq, p) | hidden_checks<BISHOP, false>(c, ksq, p);
-}
+  // Pinned pieces protect our king, dicovery checks attack
+  // the enemy king.
+  Square ksq = king_square(FindPinned ? c : opposite_color(c));
 
 
+  // Pinners are sliders, not checkers, that give check when
+  // candidate pinned is removed.
+  pinners =  (rooks_and_queens(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq])
+           | (bishops_and_queens(FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq]);
 
 
-/// Position:hidden_checks<>() returns a bitboard of all pinned (against the
-/// king) pieces for the given color and for the given pinner type. Or, when
-/// template parameter FindPinned is false, the pinned pieces of opposite color
-/// that are, indeed, the pieces candidate for a discovery check.
-/// Note that checkersBB bitboard must be already updated.
-template<PieceType Piece, bool FindPinned>
-Bitboard Position::hidden_checks(Color c, Square ksq, Bitboard& pinners) const {
+  if (FindPinned && pinners)
+      pinners &= ~st->checkersBB;
 
 
-  Square s;
-  Bitboard sliders, result = EmptyBoardBB;
+  while (pinners)
+  {
+      Square s = pop_1st_bit(&pinners);
+      Bitboard b = squares_between(s, ksq) & occupied_squares();
 
 
-  if (Piece == ROOK) // Resolved at compile time
-      sliders = rooks_and_queens(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq];
-  else
-      sliders = bishops_and_queens(FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq];
+      assert(b);
 
 
-  if (sliders && (!FindPinned || (sliders & ~st->checkersBB)))
-  {
-       // King blockers are candidate pinned pieces
-      Bitboard candidate_pinned = piece_attacks<Piece>(ksq) & pieces_of_color(c);
-
-      // Pinners are sliders, not checkers, that give check when
-      // candidate pinned are removed.
-      pinners = (FindPinned ? sliders & ~st->checkersBB : sliders);
-
-      if (Piece == ROOK)
-          pinners &= rook_attacks_bb(ksq, occupied_squares() ^ candidate_pinned);
-      else
-          pinners &= bishop_attacks_bb(ksq, occupied_squares() ^ candidate_pinned);
-
-      // Finally for each pinner find the corresponding pinned piece (if same color of king)
-      // or discovery checker (if opposite color) among the candidates.
-      Bitboard p = pinners;
-      while (p)
-      {
-          s = pop_1st_bit(&p);
-          result |= (squares_between(s, ksq) & candidate_pinned);
-      }
+      if (  !(b & (b - 1)) // Only one bit set?
+          && (b & pieces_of_color(c))) // Is an our piece?
+          result |= b;
   }
   }
-  else
-      pinners = EmptyBoardBB;
-
   return result;
 }
 
   return result;
 }
 
index 8e29eb13458390ff2d4a405ffd61cebd794f46ee..ac63c11c36e612a09aa59b4e779b39bc1c74fb2e 100644 (file)
@@ -312,8 +312,8 @@ private:
   template<PieceType Piece>
   void update_checkers(Bitboard* pCheckersBB, Square ksq, Square from, Square to, Bitboard dcCandidates);
 
   template<PieceType Piece>
   void update_checkers(Bitboard* pCheckersBB, Square ksq, Square from, Square to, Bitboard dcCandidates);
 
-  template<PieceType Piece, bool FindPinned>
-  Bitboard hidden_checks(Color c, Square ksq, Bitboard& pinners) const;
+  template<bool FindPinned>
+  Bitboard hidden_checkers(Color c) const;
 
   // Computing hash keys from scratch (for initialization and debugging)
   Key compute_key() const;
 
   // Computing hash keys from scratch (for initialization and debugging)
   Key compute_key() const;
@@ -566,6 +566,14 @@ inline Bitboard Position::checkers() const {
   return st->checkersBB;
 }
 
   return st->checkersBB;
 }
 
+inline Bitboard Position::pinned_pieces(Color c) const {
+  return hidden_checkers<true>(c);
+}
+
+inline Bitboard Position::discovered_check_candidates(Color c) const {
+  return hidden_checkers<false>(c);
+}
+
 inline bool Position::is_check() const {
   return st->checkersBB != EmptyBoardBB;
 }
 inline bool Position::is_check() const {
   return st->checkersBB != EmptyBoardBB;
 }