]> git.sesse.net Git - stockfish/blobdiff - src/position.cpp
Refactor Position::pinned_pieces() to use templates
[stockfish] / src / position.cpp
index e1d05f614738c52c485606a94526ec2a2e8e3b76..e33b65fc050e4988f646cbdc2324c9962ccb4eb8 100644 (file)
@@ -1,13 +1,14 @@
 /*
-  Glaurung, a UCI chess playing engine.
-  Copyright (C) 2004-2008 Tord Romstad
+  Stockfish, a UCI chess playing engine derived from Glaurung 2.1
+  Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
+  Copyright (C) 2008 Marco Costalba
 
-  Glaurung is free software: you can redistribute it and/or modify
+  Stockfish is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.
 
-  Glaurung is distributed in the hope that it will be useful,
+  Stockfish is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
@@ -295,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
@@ -406,8 +420,8 @@ bool Position::piece_attacks_square(Square f, Square t) const {
   assert(square_is_ok(t));
 
   switch(piece_on(f)) {
-  case WP: return white_pawn_attacks_square(f, t);
-  case BP: return black_pawn_attacks_square(f, t);
+  case WP: return pawn_attacks_square(WHITE, f, t);
+  case BP: return pawn_attacks_square(BLACK, f, t);
   case WN: case BN: return piece_attacks_square<KNIGHT>(f, t);
   case WB: case BB: return piece_attacks_square<BISHOP>(f, t);
   case WR: case BR: return piece_attacks_square<ROOK>(f, t);
@@ -668,8 +682,8 @@ bool Position::move_attacks_square(Move m, Square s) const {
   assert(square_is_occupied(f));
 
   switch(piece_on(f)) {
-  case WP: return white_pawn_attacks_square(t, s);
-  case BP: return black_pawn_attacks_square(t, s);
+  case WP: return pawn_attacks_square(WHITE, t, s);
+  case BP: return pawn_attacks_square(BLACK, t, s);
   case WN: case BN: return piece_attacks_square<KNIGHT>(t, s);
   case WB: case BB: return piece_attacks_square<BISHOP>(t, s);
   case WR: case BR: return piece_attacks_square<ROOK>(t, s);