Refactor Position::pinned_pieces() to use templates
authorMarco Costalba <mcostalba@gmail.com>
Thu, 23 Oct 2008 10:59:20 +0000 (12:59 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 24 Oct 2008 19:10:04 +0000 (21:10 +0200)
Also better document this interesting function.

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

index bc1900196d45cbc0c901158506096460195b426d..eceb845e643112d929c24a8a0b6236ab574fd589 100644 (file)
@@ -150,26 +150,16 @@ extern Bitboard QueenPseudoAttacks[64];
 /// Functions for testing whether a given bit is set in a bitboard, and for
 /// setting and clearing bits.
 
-inline Bitboard set_mask_bb(Square s) {
-  //  return 1ULL << s;
-  return SetMaskBB[s];
-}
-
-inline Bitboard clear_mask_bb(Square s) {
-  //  return ~set_mask_bb(s);
-  return ClearMaskBB[s];
-}
-
 inline Bitboard bit_is_set(Bitboard b, Square s) {
-  return b & set_mask_bb(s);
+  return b & SetMaskBB[s];
 }
 
 inline void set_bit(Bitboard *b, Square s) {
-  *b |= set_mask_bb(s);
+  *b |= SetMaskBB[s];
 }
 
 inline void clear_bit(Bitboard *b, Square s) {
-  *b &= clear_mask_bb(s);
+  *b &= ClearMaskBB[s];
 }
 
 
index 8f3ef1cd78d4711de49065bf82ccb36d3c80a171..a7e5f2d5b8ccf333c8daf583c664946d2c816a8b 100644 (file)
@@ -778,7 +778,7 @@ namespace {
             while (b)
             {
                 Square from, to = pop_1st_bit(&b);
-                if (!(escapeSquares & ~queen_attacks_bb(to, occ & clear_mask_bb(s))))
+                if (!(escapeSquares & ~queen_attacks_bb(to, occ & ClearMaskBB[s])))
                 {
                     // We have a mate, unless the queen is pinned or there
                     // is an X-ray attack through the queen.
@@ -787,8 +787,8 @@ namespace {
                         from = p.piece_list(them, QUEEN, i);
                         if (    bit_is_set(p.piece_attacks<QUEEN>(from), to)
                             && !bit_is_set(p.pinned_pieces(them), from)
-                            && !(rook_attacks_bb(to, occ & clear_mask_bb(from)) & p.rooks_and_queens(us))
-                            && !(rook_attacks_bb(to, occ & clear_mask_bb(from)) & p.rooks_and_queens(us)))
+                            && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.rooks_and_queens(us))
+                            && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.rooks_and_queens(us)))
                             
                             ei.mateThreat[them] = make_move(from, to);
                     }
index ff93e532d999c3012e4774a35ea98a1e07c4417b..e33b65fc050e4988f646cbdc2324c9962ccb4eb8 100644 (file)
@@ -296,40 +296,53 @@ void Position::copy(const Position &pos) {
 }
 
 
-/// Position:pinned_pieces() returns a bitboard of all pinned (against the
-/// king) pieces for the given color.
+/// Position:pinned_pieces<>() returns a bitboard of all pinned (against the
+/// king) pieces for the given color and for the given pinner type.
+template<PieceType Piece>
+Bitboard Position::pinned_pieces(Color c, Square ksq) const {
 
-Bitboard Position::pinned_pieces(Color c) const {
-  Bitboard b1, b2, pinned, pinners, sliders;
-  Square ksq = king_square(c), s;
-  Color them = opposite_color(c);
+  Square s;
+  Bitboard sliders, pinned = EmptyBoardBB;
+  
+  if (Piece == ROOK) // Resolved at compile time
+      sliders = rooks_and_queens(opposite_color(c)) & RookPseudoAttacks[ksq];
+  else
+      sliders = bishops_and_queens(opposite_color(c)) & BishopPseudoAttacks[ksq];
 
-  pinned = EmptyBoardBB;
-  b1 = occupied_squares();
+  if (sliders && (sliders & ~checkersBB))
+  {
+       // Our 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.
+      Bitboard pinners =  sliders & ~checkersBB;
+      if (Piece == ROOK)
+          pinners &= rook_attacks_bb(ksq, occupied_squares() ^ candidate_pinned);
+      else
+          pinners &= bishop_attacks_bb(ksq, occupied_squares() ^ candidate_pinned);
 
-  sliders = rooks_and_queens(them) & ~checkers();
-  if(sliders & RookPseudoAttacks[ksq]) {
-    b2 = piece_attacks<ROOK>(ksq) & pieces_of_color(c);
-    pinners = rook_attacks_bb(ksq, b1 ^ b2) & sliders;
-    while(pinners) {
-      s = pop_1st_bit(&pinners);
-      pinned |= (squares_between(s, ksq) & b2);
-    }
+      // Finally for each pinner find the corresponding pinned piece
+      // among the candidates.
+      while (pinners)
+      {
+          s = pop_1st_bit(&pinners);
+          pinned |= (squares_between(s, ksq) & candidate_pinned);
+      }
   }
+  return pinned;
+}
 
-  sliders = bishops_and_queens(them) & ~checkers();
-  if(sliders & BishopPseudoAttacks[ksq]) {
-    b2 = piece_attacks<BISHOP>(ksq) & pieces_of_color(c);
-    pinners = bishop_attacks_bb(ksq, b1 ^ b2) & sliders;
-    while(pinners) {
-      s = pop_1st_bit(&pinners);
-      pinned |= (squares_between(s, ksq) & b2);
-    }
-  }
 
-  return pinned;
+/// Position:pinned_pieces() returns a bitboard of all pinned (against the
+/// king) pieces for the given color.
+Bitboard Position::pinned_pieces(Color c) const {
+
+  Square ksq = king_square(c);
+  return pinned_pieces<ROOK>(c, ksq) | pinned_pieces<BISHOP>(c, ksq);
 }
 
+
 /// 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
index 48f40dac47e66598b97f1384490861cc6c2ac7aa..5ae75655658fc69276391a6aafcf4b5d02453c45 100644 (file)
@@ -197,6 +197,8 @@ public:
   // Bitboards for pinned pieces and discovered check candidates
   Bitboard discovered_check_candidates(Color c) const;
   Bitboard pinned_pieces(Color c) const;
+  template<PieceType Piece>
+  Bitboard pinned_pieces(Color c, Square ksq) const;
 
   // Checking pieces
   Bitboard checkers() const;
@@ -553,7 +555,7 @@ inline Bitboard Position::checkers() const {
 }
 
 inline bool Position::is_check() const {
-  return checkers() != EmptyBoardBB;
+  return checkersBB != EmptyBoardBB;
 }
 
 inline bool Position::pawn_attacks_square(Color c, Square f, Square t) const {