Prefer template to name decoration
authorMarco Costalba <mcostalba@gmail.com>
Sun, 19 Oct 2008 11:43:09 +0000 (12:43 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Mon, 20 Oct 2008 19:47:16 +0000 (21:47 +0200)
This also allows faster code although bigger.

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

index 7a47a3e170f9d908ba808b79c0ed25b911e82763..366a02d1137458b80085034af0577b4a82903e18 100644 (file)
@@ -489,7 +489,7 @@ ScaleFactor KQKRPScalingFunction::apply(const Position &pos) {
      relative_rank(weakerSide, pos.king_square(strongerSide)) >= RANK_4 &&
      (pos.rooks(weakerSide) & relative_rank_bb(weakerSide, RANK_3)) &&
      (pos.pawns(weakerSide) & relative_rank_bb(weakerSide, RANK_2)) &&
-     (pos.king_attacks(kingSq) & pos.pawns(weakerSide))) {
+     (pos.piece_attacks<KING>(kingSq) & pos.pawns(weakerSide))) {
     Square rsq = pos.rook_list(weakerSide, 0);
     if(pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide))
       return ScaleFactor(0);
@@ -732,7 +732,7 @@ ScaleFactor KBPKBScalingFunction::apply(const Position &pos) {
         ray_bb(pawnSq, (strongerSide == WHITE)? SIGNED_DIR_N : SIGNED_DIR_S);
       if(ray & pos.kings(weakerSide))
         return ScaleFactor(0);
-      if((pos.bishop_attacks(weakerBishopSq) & ray)
+      if((pos.piece_attacks<BISHOP>(weakerBishopSq) & ray)
          && square_distance(weakerBishopSq, pawnSq) >= 3)
         return ScaleFactor(0);
     }
index 864af221de16ce2e490c5c13e8309c9a64ba5ada..4bda8466e1fdaeddc3e346376d4a37f2a038dbae 100644 (file)
@@ -322,8 +322,8 @@ Value evaluate(const Position &pos, EvalInfo &ei, int threadID) {
   ei.egValue += apply_weight(ei.pi->eg_value(), WeightPawnStructureEndgame);
 
   // Initialize king attack bitboards and king attack zones for both sides
-  ei.attackedBy[WHITE][KING] = pos.king_attacks(pos.king_square(WHITE));
-  ei.attackedBy[BLACK][KING] = pos.king_attacks(pos.king_square(BLACK));
+  ei.attackedBy[WHITE][KING] = pos.piece_attacks<KING>(pos.king_square(WHITE));
+  ei.attackedBy[BLACK][KING] = pos.piece_attacks<KING>(pos.king_square(BLACK));
   ei.kingZone[WHITE] = ei.attackedBy[BLACK][KING] | (ei.attackedBy[BLACK][KING] >> 8);
   ei.kingZone[BLACK] = ei.attackedBy[WHITE][KING] | (ei.attackedBy[WHITE][KING] << 8);
 
@@ -584,7 +584,7 @@ namespace {
 
   void evaluate_knight(const Position &p, Square s, Color us, EvalInfo &ei) {
 
-    Bitboard b = p.knight_attacks(s);
+    Bitboard b = p.piece_attacks<KNIGHT>(s);
     ei.attackedBy[us][KNIGHT] |= b;
 
     // King attack, mobility and outposts
@@ -679,7 +679,7 @@ namespace {
 
   void evaluate_queen(const Position &p, Square s, Color us, EvalInfo &ei) {
 
-    Bitboard b = p.queen_attacks(s);
+    Bitboard b = p.piece_attacks<QUEEN>(s);
     ei.attackedBy[us][QUEEN] |= b;
 
     // King attack and mobility
@@ -772,7 +772,7 @@ namespace {
           if (QueenContactMates && !p.is_check())
           {
             Bitboard escapeSquares =
-                p.king_attacks(s) & ~p.pieces_of_color(us) & ~attackedByOthers;
+                p.piece_attacks<KING>(s) & ~p.pieces_of_color(us) & ~attackedByOthers;
 
             while (b)
             {
@@ -784,7 +784,7 @@ namespace {
                     for (int i = 0; i < p.queen_count(them); i++)
                     {
                         from = p.queen_list(them, i);
-                        if (    bit_is_set(p.queen_attacks(from), to)
+                        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)))
@@ -817,7 +817,7 @@ namespace {
       // Analyse safe distance checks:
       if (QueenCheckBonus > 0 || RookCheckBonus > 0)
       {
-          b = p.rook_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us);
+          b = p.piece_attacks<ROOK>(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us);
 
           // Queen checks
           b2 = b & ei.attacked_by(them, QUEEN);
@@ -831,7 +831,7 @@ namespace {
       }
       if (QueenCheckBonus > 0 || BishopCheckBonus > 0)
       {
-          b = p.bishop_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us);
+          b = p.piece_attacks<BISHOP>(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us);
 
           // Queen checks
           b2 = b & ei.attacked_by(them, QUEEN);
@@ -845,7 +845,7 @@ namespace {
       }
       if (KnightCheckBonus > 0)
       {
-          b = p.knight_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us);
+          b = p.piece_attacks<KNIGHT>(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us);
 
           // Knight checks
           b2 = b & ei.attacked_by(them, KNIGHT);
index 0646c230f50c778360a48c368258d47998df2e68..259d276b3d79f122de26a1ad4c826fd671498bf4 100644 (file)
@@ -59,11 +59,17 @@ namespace {
   int generate_pawn_captures(const PawnOffsets&, const Position&, MoveStack*);  
   int generate_pawn_noncaptures(const PawnOffsets&, const Position&, MoveStack*);
   int generate_pawn_checks(const PawnOffsets&, const Position&, Bitboard, Square, MoveStack*, int);
-  int generate_piece_checks(PieceType, const Position&, Bitboard, Bitboard, Square, MoveStack*, int);
-  int generate_piece_moves(PieceType, const Position&, MoveStack*, Color, Bitboard);
   int generate_castle_moves(const Position&, MoveStack*, Color);
-  int generate_piece_blocking_evasions(PieceType, const Position&, Bitboard, Bitboard, MoveStack*, int);
   int generate_pawn_blocking_evasions(const PawnOffsets&, const Position&, Bitboard, Bitboard, MoveStack*, int);
+
+  template<PieceType>
+  int generate_piece_moves(const Position&, MoveStack*, Color, Bitboard);
+
+  template<PieceType>
+  int generate_piece_checks(const Position&, Bitboard, Bitboard, Square, MoveStack*, int);
+
+  template<PieceType>
+  int generate_piece_blocking_evasions(const Position&, Bitboard, Bitboard, MoveStack*, int);
 }
 
 
@@ -89,9 +95,11 @@ int generate_captures(const Position& pos, MoveStack* mlist) {
   else
       n = generate_pawn_captures(BlackPawnOffsets, pos, mlist);
 
-  for (PieceType pce = KNIGHT; pce <= KING; pce++)
-      n += generate_piece_moves(pce, pos, mlist+n, us, target);
-
+  n += generate_piece_moves<KNIGHT>(pos, mlist+n, us, target);
+  n += generate_piece_moves<BISHOP>(pos, mlist+n, us, target);
+  n += generate_piece_moves<ROOK>(pos, mlist+n, us, target);
+  n += generate_piece_moves<QUEEN>(pos, mlist+n, us, target);
+  n += generate_piece_moves<KING>(pos, mlist+n, us, target);
   return n;
 }
 
@@ -113,8 +121,11 @@ int generate_noncaptures(const Position& pos, MoveStack *mlist) {
   else
       n = generate_pawn_noncaptures(BlackPawnOffsets, pos, mlist);
 
-  for (PieceType pce = KNIGHT; pce <= KING; pce++)
-      n += generate_piece_moves(pce, pos, mlist+n, us, target);
+  n += generate_piece_moves<KNIGHT>(pos, mlist+n, us, target);
+  n += generate_piece_moves<BISHOP>(pos, mlist+n, us, target);
+  n += generate_piece_moves<ROOK>(pos, mlist+n, us, target);
+  n += generate_piece_moves<QUEEN>(pos, mlist+n, us, target);
+  n += generate_piece_moves<KING>(pos, mlist+n, us, target);
 
   n += generate_castle_moves(pos, mlist+n, us);
   return n;
@@ -147,25 +158,25 @@ int generate_checks(const Position& pos, MoveStack* mlist, Bitboard dc) {
   // Pieces moves
   Bitboard b = pos.knights(us);
   if (b)
-      n = generate_piece_checks(KNIGHT, pos, b, dc, ksq, mlist, n);
+      n = generate_piece_checks<KNIGHT>(pos, b, dc, ksq, mlist, n);
 
   b = pos.bishops(us);
   if (b)
-      n = generate_piece_checks(BISHOP, pos, b, dc, ksq, mlist, n);
+      n = generate_piece_checks<BISHOP>(pos, b, dc, ksq, mlist, n);
 
   b = pos.rooks(us);
   if (b)
-      n = generate_piece_checks(ROOK, pos, b, dc, ksq, mlist, n);
+      n = generate_piece_checks<ROOK>(pos, b, dc, ksq, mlist, n);
 
   b = pos.queens(us);
   if (b)
-      n = generate_piece_checks(QUEEN, pos, b, dc, ksq, mlist, n);
+      n = generate_piece_checks<QUEEN>(pos, b, dc, ksq, mlist, n);
 
   // King moves
   Square from = pos.king_square(us);
   if (bit_is_set(dc, from))
   {
-      b = pos.king_attacks(from) & pos.empty_squares() & ~QueenPseudoAttacks[ksq];
+      b = pos.piece_attacks<KING>(from) & pos.empty_squares() & ~QueenPseudoAttacks[ksq];
       while (b)
       {
           Square to = pop_1st_bit(&b);
@@ -198,7 +209,7 @@ int generate_evasions(const Position& pos, MoveStack* mlist) {
   assert(pos.piece_on(ksq) == king_of_color(us));
   
   // Generate evasions for king
-  Bitboard b1 = pos.king_attacks(ksq) & ~pos.pieces_of_color(us);
+  Bitboard b1 = pos.piece_attacks<KING>(ksq) & ~pos.pieces_of_color(us);
   Bitboard b2 = pos.occupied_squares();
   clear_bit(&b2, ksq);
 
@@ -213,9 +224,9 @@ int generate_evasions(const Position& pos, MoveStack* mlist) {
     // the king will remain in check on the destination square.
     if (!(   (bishop_attacks_bb(to, b2)  & pos.bishops_and_queens(them))
           || (rook_attacks_bb(to, b2)    & pos.rooks_and_queens(them))
-          || (pos.knight_attacks(to)     & pos.knights(them))
+          || (pos.piece_attacks<KNIGHT>(to)     & pos.knights(them))
           || (pos.pawn_attacks(us, to)   & pos.pawns(them))
-          || (pos.king_attacks(to)       & pos.kings(them))))
+          || (pos.piece_attacks<KING>(to)       & pos.kings(them))))
 
         mlist[n++].move = make_move(ksq, to);
   }
@@ -252,9 +263,9 @@ int generate_evasions(const Position& pos, MoveStack* mlist) {
       }
 
       // Pieces captures
-      b1 = (  (pos.knight_attacks(checksq) & pos.knights(us))
-            | (pos.bishop_attacks(checksq) & pos.bishops_and_queens(us))
-            | (pos.rook_attacks(checksq)   & pos.rooks_and_queens(us)) ) & not_pinned;
+      b1 = (  (pos.piece_attacks<KNIGHT>(checksq) & pos.knights(us))
+            | (pos.piece_attacks<BISHOP>(checksq) & pos.bishops_and_queens(us))
+            | (pos.piece_attacks<ROOK>(checksq)   & pos.rooks_and_queens(us)) ) & not_pinned;
 
       while (b1)
       {
@@ -280,19 +291,19 @@ int generate_evasions(const Position& pos, MoveStack* mlist) {
           // Pieces moves
           b1 = pos.knights(us) & not_pinned;
           if (b1)
-              n = generate_piece_blocking_evasions(KNIGHT, pos, b1, blockSquares, mlist, n);
+              n = generate_piece_blocking_evasions<KNIGHT>(pos, b1, blockSquares, mlist, n);
 
           b1 = pos.bishops(us) & not_pinned;
           if (b1)
-              n = generate_piece_blocking_evasions(BISHOP, pos, b1, blockSquares, mlist, n);
+              n = generate_piece_blocking_evasions<BISHOP>(pos, b1, blockSquares, mlist, n);
 
           b1 = pos.rooks(us) & not_pinned;
           if (b1)
-              n = generate_piece_blocking_evasions(ROOK, pos, b1, blockSquares, mlist, n);
+              n = generate_piece_blocking_evasions<ROOK>(pos, b1, blockSquares, mlist, n);
 
           b1 = pos.queens(us) & not_pinned;
           if (b1)
-              n = generate_piece_blocking_evasions(QUEEN, pos, b1, blockSquares, mlist, n);
+              n = generate_piece_blocking_evasions<QUEEN>(pos, b1, blockSquares, mlist, n);
     }
 
     // Finally, the ugly special case of en passant captures. An en passant
@@ -669,18 +680,18 @@ namespace {
   }
 
 
-  int generate_piece_moves(PieceType piece, const Position &pos, MoveStack *mlist, 
+  template<PieceType Piece>
+  int generate_piece_moves(const Position &pos, MoveStack *mlist, 
                            Color side, Bitboard target) {
 
-    const Piece_attacks_fn mem_fn = piece_attacks_fn[piece];
     Square from, to;
     Bitboard b;
     int n = 0;
 
-    for (int i = 0; i < pos.piece_count(side, piece); i++)
+    for (int i = 0; i < pos.piece_count(side, Piece); i++)
     {
-        from = pos.piece_list(side, piece, i);
-        b = (pos.*mem_fn)(from) & target;
+        from = pos.piece_list(side, Piece, i);
+        b = pos.piece_attacks<Piece>(from) & target;
         while (b)
         {
             to = pop_1st_bit(&b);
@@ -756,17 +767,16 @@ namespace {
     return n;
   }
 
-  int generate_piece_checks(PieceType pce, const Position& pos, Bitboard target,
-                          Bitboard dc, Square ksq, MoveStack* mlist, int n) {
-
-    const Piece_attacks_fn mem_fn = piece_attacks_fn[pce];
+  template<PieceType Piece>
+  int generate_piece_checks(const Position& pos, Bitboard target, Bitboard dc,
+                            Square ksq, MoveStack* mlist, int n) {
 
     // Discovered checks
     Bitboard b = target & dc;
     while (b)
     {
         Square from = pop_1st_bit(&b);
-        Bitboard bb = (pos.*mem_fn)(from) & pos.empty_squares();
+        Bitboard bb = pos.piece_attacks<Piece>(from) & pos.empty_squares();
         while (bb)
         {
             Square to = pop_1st_bit(&bb);
@@ -776,11 +786,11 @@ namespace {
 
     // Direct checks
     b = target & ~dc;
-    Bitboard checkSqs = (pos.*mem_fn)(ksq) & pos.empty_squares();
+    Bitboard checkSqs = pos.piece_attacks<Piece>(ksq) & pos.empty_squares();
     while (b)
     {
         Square from = pop_1st_bit(&b);
-        Bitboard bb = (pos.*mem_fn)(from) & checkSqs;
+        Bitboard bb = pos.piece_attacks<Piece>(from) & checkSqs;
         while (bb)
         {
             Square to = pop_1st_bit(&bb);
@@ -841,15 +851,13 @@ namespace {
   }
 
 
-   int generate_piece_blocking_evasions(PieceType pce, const Position& pos, Bitboard b,
+   template<PieceType Piece>
+   int generate_piece_blocking_evasions(const Position& pos, Bitboard b,
                                         Bitboard blockSquares, MoveStack* mlist, int n) {
-
-    const Piece_attacks_fn mem_fn = piece_attacks_fn[pce];
-
     while (b)
     {
         Square from = pop_1st_bit(&b);
-        Bitboard bb = (pos.*mem_fn)(from) & blockSquares;
+        Bitboard bb = pos.piece_attacks<Piece>(from) & blockSquares;
         while (bb)
         {
             Square to = pop_1st_bit(&bb);
index ba57657e11b81000f6026116646af2f10b490c50..e32f8f4973cf4e06f913067baae7e4f38d014318 100644 (file)
@@ -48,13 +48,6 @@ Key Position::zobSideToMove;
 Value Position::MgPieceSquareTable[16][64];
 Value Position::EgPieceSquareTable[16][64];
 
-const Piece_attacks_fn piece_attacks_fn[] =
-  { 0, 0, 
-    &Position::knight_attacks,
-    &Position::bishop_attacks,
-    &Position::rook_attacks,
-    &Position::queen_attacks,
-    &Position::king_attacks };
 
 ////
 //// Functions
@@ -315,7 +308,7 @@ Bitboard Position::pinned_pieces(Color c) const {
 
   sliders = rooks_and_queens(them) & ~checkers();
   if(sliders & RookPseudoAttacks[ksq]) {
-    b2 = rook_attacks(ksq) & pieces_of_color(c);
+    b2 = piece_attacks<ROOK>(ksq) & pieces_of_color(c);
     pinners = rook_attacks_bb(ksq, b1 ^ b2) & sliders;
     while(pinners) {
       s = pop_1st_bit(&pinners);
@@ -325,7 +318,7 @@ Bitboard Position::pinned_pieces(Color c) const {
 
   sliders = bishops_and_queens(them) & ~checkers();
   if(sliders & BishopPseudoAttacks[ksq]) {
-    b2 = bishop_attacks(ksq) & pieces_of_color(c);
+    b2 = piece_attacks<BISHOP>(ksq) & pieces_of_color(c);
     pinners = bishop_attacks_bb(ksq, b1 ^ b2) & sliders;
     while(pinners) {
       s = pop_1st_bit(&pinners);
@@ -350,7 +343,7 @@ Bitboard Position::discovered_check_candidates(Color c) const {
 
   sliders = rooks_and_queens(c);
   if(sliders & RookPseudoAttacks[ksq]) {
-    b2 = rook_attacks(ksq) & pieces_of_color(c);
+    b2 = piece_attacks<ROOK>(ksq) & pieces_of_color(c);
     checkers = rook_attacks_bb(ksq, b1 ^ b2) & sliders;
     while(checkers) {
       s = pop_1st_bit(&checkers);
@@ -360,7 +353,7 @@ Bitboard Position::discovered_check_candidates(Color c) const {
 
   sliders = bishops_and_queens(c);
   if(sliders & BishopPseudoAttacks[ksq]) {
-    b2 = bishop_attacks(ksq) & pieces_of_color(c);
+    b2 = piece_attacks<BISHOP>(ksq) & pieces_of_color(c);
     checkers = bishop_attacks_bb(ksq, b1 ^ b2) & sliders;
     while(checkers) {
       s = pop_1st_bit(&checkers);
@@ -378,10 +371,10 @@ Bitboard Position::discovered_check_candidates(Color c) const {
 bool Position::square_is_attacked(Square s, Color c) const {
   return
     (pawn_attacks(opposite_color(c), s) & pawns(c)) ||
-    (knight_attacks(s) & knights(c)) ||
-    (king_attacks(s) & kings(c)) ||
-    (rook_attacks(s) & rooks_and_queens(c)) ||
-    (bishop_attacks(s) & bishops_and_queens(c));
+    (piece_attacks<KNIGHT>(s) & knights(c)) ||
+    (piece_attacks<KING>(s)   & kings(c)) ||
+    (piece_attacks<ROOK>(s)   & rooks_and_queens(c)) ||
+    (piece_attacks<BISHOP>(s) & bishops_and_queens(c));
 }
 
 
@@ -394,10 +387,10 @@ Bitboard Position::attacks_to(Square s) const {
   return
     (black_pawn_attacks(s) & pawns(WHITE)) |
     (white_pawn_attacks(s) & pawns(BLACK)) |
-    (knight_attacks(s) & pieces_of_type(KNIGHT)) |
-    (rook_attacks(s) & rooks_and_queens()) |
-    (bishop_attacks(s) & bishops_and_queens()) |
-    (king_attacks(s) & pieces_of_type(KING));
+    (piece_attacks<KNIGHT>(s) & pieces_of_type(KNIGHT)) |
+    (piece_attacks<ROOK>(s) & rooks_and_queens()) |
+    (piece_attacks<BISHOP>(s) & bishops_and_queens()) |
+    (piece_attacks<KING>(s) & pieces_of_type(KING));
 }
 
 Bitboard Position::attacks_to(Square s, Color c) const {
@@ -588,7 +581,7 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const {
       return true;
     // Normal check?
     else
-      return bit_is_set(knight_attacks(ksq), to);
+      return bit_is_set(piece_attacks<KNIGHT>(ksq), to);
 
   case BISHOP:
     // Discovered check?
@@ -596,7 +589,7 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const {
       return true;
     // Normal check?
     else
-      return bit_is_set(bishop_attacks(ksq), to);
+      return bit_is_set(piece_attacks<BISHOP>(ksq), to);
 
   case ROOK:
     // Discovered check?
@@ -604,13 +597,13 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const {
       return true;
     // Normal check?
     else
-      return bit_is_set(rook_attacks(ksq), to);
+      return bit_is_set(piece_attacks<ROOK>(ksq), to);
 
   case QUEEN:
     // Discovered checks are impossible!
     assert(!bit_is_set(dcCandidates, from));
     // Normal check?
-    return bit_is_set(queen_attacks(ksq), to);
+    return bit_is_set(piece_attacks<QUEEN>(ksq), to);
 
   case KING:
     // Discovered check?
@@ -889,45 +882,45 @@ void Position::do_move(Move m, UndoInfo &u, Bitboard dcCandidates) {
         set_bit(&checkersBB, to);
       if(bit_is_set(dcCandidates, from))
         checkersBB |=
-          ((rook_attacks(ksq) & rooks_and_queens(us)) |
-           (bishop_attacks(ksq) & bishops_and_queens(us)));
+          ((piece_attacks<ROOK>(ksq) & rooks_and_queens(us)) |
+           (piece_attacks<BISHOP>(ksq) & bishops_and_queens(us)));
       break;
 
     case KNIGHT:
-      if(bit_is_set(knight_attacks(ksq), to))
+      if(bit_is_set(piece_attacks<KNIGHT>(ksq), to))
         set_bit(&checkersBB, to);
       if(bit_is_set(dcCandidates, from))
         checkersBB |=
-          ((rook_attacks(ksq) & rooks_and_queens(us)) |
-           (bishop_attacks(ksq) & bishops_and_queens(us)));
+          ((piece_attacks<ROOK>(ksq) & rooks_and_queens(us)) |
+           (piece_attacks<BISHOP>(ksq) & bishops_and_queens(us)));
       break;
 
     case BISHOP:
-      if(bit_is_set(bishop_attacks(ksq), to))
+      if(bit_is_set(piece_attacks<BISHOP>(ksq), to))
         set_bit(&checkersBB, to);
       if(bit_is_set(dcCandidates, from))
         checkersBB |=
-          (rook_attacks(ksq) & rooks_and_queens(us));
+          (piece_attacks<ROOK>(ksq) & rooks_and_queens(us));
       break;
 
     case ROOK:
-      if(bit_is_set(rook_attacks(ksq), to))
+      if(bit_is_set(piece_attacks<ROOK>(ksq), to))
         set_bit(&checkersBB, to);
       if(bit_is_set(dcCandidates, from))
         checkersBB |=
-          (bishop_attacks(ksq) & bishops_and_queens(us));
+          (piece_attacks<BISHOP>(ksq) & bishops_and_queens(us));
       break;
 
     case QUEEN:
-      if(bit_is_set(queen_attacks(ksq), to))
+      if(bit_is_set(piece_attacks<QUEEN>(ksq), to))
         set_bit(&checkersBB, to);
       break;
 
     case KING:
       if(bit_is_set(dcCandidates, from))
         checkersBB |=
-          ((rook_attacks(ksq) & rooks_and_queens(us)) |
-           (bishop_attacks(ksq) & bishops_and_queens(us)));
+          ((piece_attacks<ROOK>(ksq) & rooks_and_queens(us)) |
+           (piece_attacks<BISHOP>(ksq) & bishops_and_queens(us)));
       break;
 
     default:
@@ -1637,8 +1630,8 @@ int Position::see(Square from, Square to) const {
   attackers =
     (rook_attacks_bb(to, occ) & rooks_and_queens()) |
     (bishop_attacks_bb(to, occ) & bishops_and_queens()) |
-    (knight_attacks(to) & knights()) |
-    (king_attacks(to) & kings()) |
+    (piece_attacks<KNIGHT>(to) & knights()) |
+    (piece_attacks<KING>(to) & kings()) |
     (white_pawn_attacks(to) & pawns(BLACK)) |
     (black_pawn_attacks(to) & pawns(WHITE));
   attackers &= occ;
index ca233aa31d53d0dc70a715a35420164d345ea615..7e5aa8660c0e150b4a0d8934220a1aa3535d5902 100644 (file)
@@ -196,11 +196,9 @@ public:
   Bitboard pawn_attacks(Color c, Square s) const;
   Bitboard white_pawn_attacks(Square s) const;
   Bitboard black_pawn_attacks(Square s) const;
-  Bitboard knight_attacks(Square s) const;
-  Bitboard bishop_attacks(Square s) const;
-  Bitboard rook_attacks(Square s) const;
-  Bitboard queen_attacks(Square s) const;
-  Bitboard king_attacks(Square s) const;
+
+  template<PieceType>
+  Bitboard piece_attacks(Square s) const;
 
   // Bitboards for pinned pieces and discovered check candidates
   Bitboard discovered_check_candidates(Color c) const;
@@ -370,10 +368,6 @@ private:
 };
 
 
-/// An array of member functions to dispatch attacks_square
-typedef Bitboard (Position::* Piece_attacks_fn)(Square s) const;
-extern const Piece_attacks_fn piece_attacks_fn[];
-
 ////
 //// Inline functions
 ////
@@ -590,23 +584,28 @@ inline Bitboard Position::black_pawn_attacks(Square s) const {
   return pawn_attacks(BLACK, s);
 }
 
-inline Bitboard Position::knight_attacks(Square s) const {
+template<>
+inline Bitboard Position::piece_attacks<KNIGHT>(Square s) const {
   return StepAttackBB[KNIGHT][s];
 }
 
-inline Bitboard Position::rook_attacks(Square s) const {
-  return rook_attacks_bb(s, occupied_squares());
+template<>
+inline Bitboard Position::piece_attacks<BISHOP>(Square s) const {
+  return bishop_attacks_bb(s, occupied_squares());
 }
 
-inline Bitboard Position::bishop_attacks(Square s) const {
-  return bishop_attacks_bb(s, occupied_squares());
+template<>
+inline Bitboard Position::piece_attacks<ROOK>(Square s) const {
+  return rook_attacks_bb(s, occupied_squares());
 }
 
-inline Bitboard Position::queen_attacks(Square s) const {
-  return rook_attacks(s) | bishop_attacks(s);
+template<>
+inline Bitboard Position::piece_attacks<QUEEN>(Square s) const {
+  return piece_attacks<ROOK>(s) | piece_attacks<BISHOP>(s);
 }
 
-inline Bitboard Position::king_attacks(Square s) const {
+template<>
+inline Bitboard Position::piece_attacks<KING>(Square s) const {
   return StepAttackBB[KING][s];
 }
 
@@ -627,23 +626,23 @@ inline bool Position::black_pawn_attacks_square(Square f, Square t) const {
 }
 
 inline bool Position::knight_attacks_square(Square f, Square t) const {
-  return bit_is_set(knight_attacks(f), t);
+  return bit_is_set(piece_attacks<KNIGHT>(f), t);
 }
 
 inline bool Position::bishop_attacks_square(Square f, Square t) const {
-  return bit_is_set(bishop_attacks(f), t);
+  return bit_is_set(piece_attacks<BISHOP>(f), t);
 }
 
 inline bool Position::rook_attacks_square(Square f, Square t) const {
-  return bit_is_set(rook_attacks(f), t);
+  return bit_is_set(piece_attacks<ROOK>(f), t);
 }
 
 inline bool Position::queen_attacks_square(Square f, Square t) const {
-  return bit_is_set(queen_attacks(f), t);
+  return bit_is_set(piece_attacks<QUEEN>(f), t);
 }
 
 inline bool Position::king_attacks_square(Square f, Square t) const {
-  return bit_is_set(king_attacks(f), t);
+  return bit_is_set(piece_attacks<KING>(f), t);
 }
 
 inline bool Position::pawn_is_passed(Color c, Square s) const {