Templetize functions to get pieces by type
authorMarco Costalba <mcostalba@gmail.com>
Mon, 31 Aug 2009 15:07:03 +0000 (17:07 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 4 Sep 2009 07:21:05 +0000 (08:21 +0100)
Use a single template to get bitboard representation of
the position given the type of piece as a constant.

This removes almost 80 lines of code and introduces an
uniform notation to be used for querying for piece type.

No functional change and no performance change.

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

index d9961622e043f93f669a83cbd4d489aaa1389fc7..69d0df5114463f86119e0dfc1e4bd704aba0a2e5 100644 (file)
@@ -329,7 +329,7 @@ Value EvaluationFunction<KBBKN>::apply(const Position& pos) {
   assert(pos.non_pawn_material(strongerSide) == 2*BishopValueMidgame);
   assert(pos.piece_count(weakerSide, KNIGHT) == 1);
   assert(pos.non_pawn_material(weakerSide) == KnightValueMidgame);
-  assert(pos.pawns() == EmptyBoardBB);
+  assert(pos.pieces<PAWN>() == EmptyBoardBB);
 
   Value result = BishopValueEndgame;
   Square wksq = pos.king_square(strongerSide);
@@ -376,7 +376,7 @@ ScaleFactor ScalingFunction<KBPsK>::apply(const Position& pos) {
   // No assertions about the material of weakerSide, because we want draws to
   // be detected even when the weaker side has some pawns.
 
-  Bitboard pawns = pos.pawns(strongerSide);
+  Bitboard pawns = pos.pieces<PAWN>(strongerSide);
   File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));
 
   // All pawns are on a single rook file ?
@@ -432,12 +432,12 @@ ScaleFactor ScalingFunction<KQKRPs>::apply(const Position& pos) {
   Square kingSq = pos.king_square(weakerSide);
   if (   relative_rank(weakerSide, kingSq) <= RANK_2
       && 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.piece_attacks<KING>(kingSq) & pos.pawns(weakerSide)))
+      && (pos.pieces<ROOK>(weakerSide) & relative_rank_bb(weakerSide, RANK_3))
+      && (pos.pieces<PAWN>(weakerSide) & relative_rank_bb(weakerSide, RANK_2))
+      && (pos.piece_attacks<KING>(kingSq) & pos.pieces<PAWN>(weakerSide)))
   {
       Square rsq = pos.piece_list(weakerSide, ROOK, 0);
-      if (pos.pawn_attacks(strongerSide, rsq) & pos.pawns(weakerSide))
+      if (pos.pawn_attacks(strongerSide, rsq) & pos.pieces<PAWN>(weakerSide))
           return ScaleFactor(0);
   }
   return SCALE_FACTOR_NONE;
@@ -616,7 +616,7 @@ ScaleFactor ScalingFunction<KPsK>::apply(const Position &pos) {
   assert(pos.non_pawn_material(weakerSide) == Value(0));
   assert(pos.piece_count(weakerSide, PAWN) == 0);
 
-  Bitboard pawns = pos.pawns(strongerSide);
+  Bitboard pawns = pos.pieces<PAWN>(strongerSide);
 
   // Are all pawns on the 'a' file?
   if ((pawns & ~FileABB) == EmptyBoardBB)
@@ -694,7 +694,7 @@ ScaleFactor ScalingFunction<KBPKB>::apply(const Position &pos) {
       else
       {
           Bitboard ray = ray_bb(pawnSq, (strongerSide == WHITE)? SIGNED_DIR_N : SIGNED_DIR_S);
-          if (ray & pos.kings(weakerSide))
+          if (ray & pos.pieces<KING>(weakerSide))
               return ScaleFactor(0);
           if(  (pos.piece_attacks<BISHOP>(weakerBishopSq) & ray)
              && square_distance(weakerBishopSq, pawnSq) >= 3)
@@ -761,13 +761,13 @@ ScaleFactor ScalingFunction<KBPPKB>::apply(const Position& pos) {
     if (   ksq == blockSq1
         && square_color(ksq) != square_color(wbsq)
         && (   bbsq == blockSq2
-            || (pos.piece_attacks<BISHOP>(blockSq2) & pos.bishops(weakerSide))
+            || (pos.piece_attacks<BISHOP>(blockSq2) & pos.pieces<BISHOP>(weakerSide))
             || rank_distance(r1, r2) >= 2))
         return ScaleFactor(0);
     else if (   ksq == blockSq2
              && square_color(ksq) != square_color(wbsq)
              && (   bbsq == blockSq1
-                 || (pos.piece_attacks<BISHOP>(blockSq1) & pos.bishops(weakerSide))))
+                 || (pos.piece_attacks<BISHOP>(blockSq1) & pos.pieces<BISHOP>(weakerSide))))
         return ScaleFactor(0);
     else
         return SCALE_FACTOR_NONE;
index a291ec466258b0bb336850e3444cffbccb4bc6f0..a1015edfa3d89bf399631e44bcf2a6bf61a9b0ba 100644 (file)
@@ -348,8 +348,8 @@ Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) {
   ei.kingZone[BLACK] = ei.attackedBy[WHITE][KING] | (ei.attackedBy[WHITE][KING] << 8);
 
   // Initialize pawn attack bitboards for both sides
-  ei.attackedBy[WHITE][PAWN] = ((pos.pawns(WHITE) << 9) & ~FileABB) | ((pos.pawns(WHITE) << 7) & ~FileHBB);
-  ei.attackedBy[BLACK][PAWN] = ((pos.pawns(BLACK) >> 7) & ~FileABB) | ((pos.pawns(BLACK) >> 9) & ~FileHBB);
+  ei.attackedBy[WHITE][PAWN] = ((pos.pieces<PAWN>(WHITE) << 9) & ~FileABB) | ((pos.pieces<PAWN>(WHITE) << 7) & ~FileHBB);
+  ei.attackedBy[BLACK][PAWN] = ((pos.pieces<PAWN>(BLACK) >> 7) & ~FileABB) | ((pos.pieces<PAWN>(BLACK) >> 9) & ~FileHBB);
   Bitboard b1 = ei.attackedBy[WHITE][PAWN] & ei.attackedBy[BLACK][KING];
   Bitboard b2 = ei.attackedBy[BLACK][PAWN] & ei.attackedBy[WHITE][KING];
   if (b1)
@@ -590,10 +590,10 @@ namespace {
 
     // Increase bonus if supported by pawn, especially if the opponent has
     // no minor piece which can exchange the outpost piece
-    if (bonus && (p.pawn_attacks(them, s) & p.pawns(us)))
+    if (bonus && (p.pawn_attacks(them, s) & p.pieces<PAWN>(us)))
     {
-        if (    p.knights(them) == EmptyBoardBB
-            && (SquaresByColorBB[square_color(s)] & p.bishops(them)) == EmptyBoardBB)
+        if (    p.pieces<KNIGHT>(them) == EmptyBoardBB
+            && (SquaresByColorBB[square_color(s)] & p.pieces<BISHOP>(them)) == EmptyBoardBB)
             bonus += bonus + bonus / 2;
         else
             bonus += bonus / 2;
@@ -622,9 +622,9 @@ namespace {
         if (Piece == KNIGHT || Piece == QUEEN)
             b = pos.piece_attacks<Piece>(s);
         else if (Piece == BISHOP)
-            b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.queens(us));
+            b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces<QUEEN>(us));
         else if (Piece == ROOK)
-            b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.rooks_and_queens(us));
+            b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces<ROOK_AND_QUEEN>(us));
         else
             assert(false);
 
@@ -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 & ClearMaskBB[from]) & p.rooks_and_queens(us))
-                            && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & p.bishops_and_queens(us)))
+                            && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces<ROOK_AND_QUEEN>(us))
+                            && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces<BISHOP_AND_QUEEN>(us)))
 
                             ei.mateThreat[them] = make_move(from, to);
                     }
@@ -841,7 +841,7 @@ namespace {
       // adding pawns later).
       if (DiscoveredCheckBonus)
       {
-        b = p.discovered_check_candidates(them) & ~p.pawns();
+        b = p.discovered_check_candidates(them) & ~p.pieces<PAWN>();
         if (b)
           attackUnits += DiscoveredCheckBonus * count_1s_max_15<HasPopCnt>(b) * (sente? 2 : 1);
       }
@@ -889,7 +889,7 @@ namespace {
         Color them = opposite_color(us);
         Square ourKingSq = pos.king_square(us);
         Square theirKingSq = pos.king_square(them);
-        Bitboard b = ei.pi->passed_pawns() & pos.pawns(us), b2, b3, b4;
+        Bitboard b = ei.pi->passed_pawns() & pos.pieces<PAWN>(us), b2, b3, b4;
 
         while (b)
         {
@@ -923,14 +923,14 @@ namespace {
                     // If there is an enemy rook or queen attacking the pawn from behind,
                     // add all X-ray attacks by the rook or queen.
                     if (    bit_is_set(ei.attacked_by(them,ROOK) | ei.attacked_by(them,QUEEN),s)
-                        && (squares_behind(us, s) & pos.rooks_and_queens(them)))
+                        && (squares_behind(us, s) & pos.pieces<ROOK_AND_QUEEN>(them)))
                         b3 = b2;
 
                     // Squares attacked or occupied by enemy pieces
                     b3 |= (b2 & pos.pieces_of_color(them));
 
                     // There are no enemy pawns in the pawn's path
-                    assert((b2 & pos.pieces_of_color(them) & pos.pieces_of_type(PAWN)) == EmptyBoardBB);
+                    assert((b2 & pos.pieces<PAWN>(them)) == EmptyBoardBB);
 
                     // Are any of the squares in the pawn's path attacked or occupied by the enemy?
                     if (b3 == EmptyBoardBB)
@@ -951,7 +951,7 @@ namespace {
             }
 
             // If the pawn is supported by a friendly pawn, increase bonus
-            b2 = pos.pawns(us) & neighboring_files_bb(s);
+            b2 = pos.pieces<PAWN>(us) & neighboring_files_bb(s);
             if (b2 & rank_bb(s))
                 ebonus += Value(r * 20);
             else if (pos.pawn_attacks(them, s) & b2)
@@ -993,7 +993,7 @@ namespace {
                 if (   pos.non_pawn_material(them) <= KnightValueMidgame
                     && pos.piece_count(them, KNIGHT) <= 1)
                     ebonus += ebonus / 4;
-                else if (pos.rooks_and_queens(them))
+                else if (pos.pieces<ROOK_AND_QUEEN>(them))
                     ebonus -= ebonus / 4;
             }
 
@@ -1115,13 +1115,13 @@ namespace {
     // pawn, or if it is undefended and attacked by an enemy piece.
 
     Bitboard safeSquares =   SpaceMask[us]
-                          & ~pos.pawns(us)
+                          & ~pos.pieces<PAWN>(us)
                           & ~ei.attacked_by(them, PAWN)
                           & ~(~ei.attacked_by(us) & ei.attacked_by(them));
 
     // Find all squares which are at most three squares behind some friendly
     // pawn.
-    Bitboard behindFriendlyPawns = pos.pawns(us);
+    Bitboard behindFriendlyPawns = pos.pieces<PAWN>(us);
     if (us == WHITE)
     {
         behindFriendlyPawns |= (behindFriendlyPawns >> 8);
index b16710588bbed14f4c1a5c7e61cc027b9188cf4c..9a20292bd010fda49a36b7ff3e060109eda749f5 100644 (file)
@@ -171,14 +171,14 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
       mi->evaluationFunction = &EvaluateKKX;
       return mi;
   }
-  else if (   pos.pawns() == EmptyBoardBB
-           && pos.rooks() == EmptyBoardBB
-           && pos.queens() == EmptyBoardBB)
+  else if (   pos.pieces<PAWN>() == EmptyBoardBB
+           && pos.pieces<ROOK>() == EmptyBoardBB
+           && pos.pieces<QUEEN>() == EmptyBoardBB)
   {
       // Minor piece endgame with at least one minor piece per side and
       // no pawns. Note that the case KmmK is already handled by KXK.
-      assert(pos.knights(WHITE) | pos.bishops(WHITE));
-      assert(pos.knights(BLACK) | pos.bishops(BLACK));
+      assert((pos.pieces<KNIGHT>(WHITE) | pos.pieces<BISHOP>(WHITE)));
+      assert((pos.pieces<KNIGHT>(BLACK) | pos.pieces<BISHOP>(BLACK)));
 
       if (   pos.piece_count(WHITE, BISHOP) + pos.piece_count(WHITE, KNIGHT) <= 2
           && pos.piece_count(BLACK, BISHOP) + pos.piece_count(BLACK, KNIGHT) <= 2)
index bf8293b1259c824b8a8a91555793080d6ccfe928..41f5b077f9468ba9c1181a82332542cbf799774e 100644 (file)
@@ -238,14 +238,14 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
   // and to be able to use square_is_attacked().
   Bitboard checkers = pos.checkers();
   Bitboard checkersAttacks = EmptyBoardBB;
-  Bitboard b = checkers & (pos.queens() | pos.bishops());
+  Bitboard b = checkers & pos.pieces<BISHOP_AND_QUEEN>();
   while (b)
   {
       from = pop_1st_bit(&b);
       checkersAttacks |= bishop_attacks_bb(from, b_noKing);
   }
 
-  b = checkers & (pos.queens() | pos.rooks());
+  b = checkers & pos.pieces<ROOK_AND_QUEEN>();
   while (b)
   {
       from = pop_1st_bit(&b);
@@ -275,7 +275,7 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
       // Generate captures of the checking piece
 
       // Pawn captures
-      b1 = pos.pawn_attacks(them, checksq) & pos.pawns(us) & ~pinned;
+      b1 = pos.pawn_attacks(them, checksq) & pos.pieces<PAWN>(us) & ~pinned;
       while (b1)
       {
           from = pop_1st_bit(&b1);
@@ -290,9 +290,9 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
       }
 
       // Pieces captures
-      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)) ) & ~pinned;
+      b1 = (  (pos.piece_attacks<KNIGHT>(checksq) & pos.pieces<KNIGHT>(us))
+            | (pos.piece_attacks<BISHOP>(checksq) & pos.pieces<BISHOP_AND_QUEEN>(us))
+            | (pos.piece_attacks<ROOK>(checksq)   & pos.pieces<ROOK_AND_QUEEN>(us)) ) & ~pinned;
 
       while (b1)
       {
@@ -302,7 +302,7 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
 
       // Blocking check evasions are possible only if the checking piece is
       // a slider.
-      if (checkers & pos.sliders())
+      if (checkers & (pos.pieces<BISHOP>() | pos.pieces<ROOK>() | pos.pieces<QUEEN>()))
       {
           Bitboard blockSquares = squares_between(checksq, ksq);
 
@@ -323,10 +323,10 @@ MoveStack* generate_evasions(const Position& pos, MoveStack* mlist, Bitboard pin
       // check. If pos.ep_square() is set, the last move made must have been
       // a double pawn push. If, furthermore, the checking piece is a pawn,
       // an en passant check evasion may be possible.
-      if (pos.ep_square() != SQ_NONE && (checkers & pos.pawns(them)))
+      if (pos.ep_square() != SQ_NONE && (checkers & pos.pieces<PAWN>(them)))
       {
           to = pos.ep_square();
-          b1 = pos.pawn_attacks(them, to) & pos.pawns(us);
+          b1 = pos.pawn_attacks(them, to) & pos.pieces<PAWN>(us);
 
           // The checking pawn cannot be a discovered (bishop) check candidate
           // otherwise we were in check also before last double push move.
@@ -675,7 +675,7 @@ namespace {
     const SquareDelta TDELTA_N = (Us == WHITE ? DELTA_N : DELTA_S);
 
     Square to;
-    Bitboard pawns = pos.pawns(Us);
+    Bitboard pawns = pos.pieces<PAWN>(Us);
     Bitboard enemyPieces = pos.pieces_of_color(opposite_color(Us));
     bool possiblePromotion = (pawns & TRank7BB);
 
@@ -725,7 +725,7 @@ namespace {
 
     Bitboard b1, b2;
     Square to;
-    Bitboard pawns = pos.pawns(Us);
+    Bitboard pawns = pos.pieces<PAWN>(Us);
     Bitboard emptySquares = pos.empty_squares();
 
     if (pawns & TRank7BB) // There is some promotion candidate ?
@@ -786,7 +786,7 @@ namespace {
 
     Square to;
     Bitboard b1, b2, b3;
-    Bitboard pawns = pos.pawns(Us);
+    Bitboard pawns = pos.pieces<PAWN>(Us);
 
     if (dc & pawns)
     {
@@ -832,7 +832,7 @@ namespace {
   MoveStack* generate_piece_checks(const Position& pos, MoveStack* mlist, Color us,
                                    Bitboard dc, Square ksq) {
 
-    Bitboard target = pos.pieces_of_color(us) & pos.pieces_of_type(Piece);
+    Bitboard target = pos.pieces<Piece>(us);
 
     // Discovered checks
     Bitboard b = target & dc;
@@ -881,7 +881,7 @@ namespace {
     Square to;
 
     // Find non-pinned pawns and push them one square
-    Bitboard b1 = move_pawns<Us, DELTA_N>(pos.pawns(Us) & ~pinned);
+    Bitboard b1 = move_pawns<Us, DELTA_N>(pos.pieces<PAWN>(Us) & ~pinned);
 
     // We don't have to AND with empty squares here,
     // because the blocking squares will always be empty.
index 96664e5c072835d37e854b90d4c6b18d50dad81c..1d8b082ed449cb55281054b156721ba79deeaf42 100644 (file)
@@ -197,8 +197,8 @@ PawnInfo* PawnInfoTable::get_pawn_info(const Position& pos) {
   for (Color us = WHITE; us <= BLACK; us++)
   {
     Color them = opposite_color(us);
-    Bitboard ourPawns = pos.pawns(us);
-    Bitboard theirPawns = pos.pawns(them);
+    Bitboard ourPawns = pos.pieces<PAWN>(us);
+    Bitboard theirPawns = pos.pieces<PAWN>(them);
     Bitboard pawns = ourPawns;
 
     // Initialize pawn storm scores by giving bonuses for open files
@@ -392,7 +392,7 @@ PawnInfo* PawnInfoTable::get_pawn_info(const Position& pos) {
 int PawnInfo::updateShelter(const Position& pos, Color c, Square ksq) {
 
   unsigned shelter = 0;
-  Bitboard pawns = pos.pawns(c) & this_and_neighboring_files_bb(ksq);
+  Bitboard pawns = pos.pieces<PAWN>(c) & this_and_neighboring_files_bb(ksq);
   unsigned r = ksq & (7 << 3);
   for (int i = 1, k = (c ? -8 : 8); i < 4; i++)
   {
index 48e26c3962edfd0791d07d6cf382efb304d3c4fd..5b93ea7dc0b97785894843b32787b7d72a874717 100644 (file)
@@ -35,7 +35,8 @@
 
 enum PieceType {
   NO_PIECE_TYPE = 0,
-  PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6
+  PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6,
+  BISHOP_AND_QUEEN = 8, ROOK_AND_QUEEN = 9
 };
 
 enum Piece {
index 9b8f779895a4337748abbc20b1e37b9dce54eaba..aa07cd51cf501abc9a6dd79593de9fb49787e576 100644 (file)
@@ -340,8 +340,8 @@ Bitboard Position::hidden_checkers(Color c) const {
 
   // 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]);
+  pinners =  (pieces<ROOK_AND_QUEEN>(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq])
+           | (pieces<BISHOP_AND_QUEEN>(FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq]);
 
   if (FindPinned && pinners)
       pinners &= ~st->checkersBB;
@@ -384,12 +384,12 @@ Bitboard Position::discovered_check_candidates(Color c) const {
 
 Bitboard Position::attacks_to(Square s) const {
 
-  return  (pawn_attacks(BLACK, s)   & pawns(WHITE))
-        | (pawn_attacks(WHITE, s)   & pawns(BLACK))
-        | (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));
+  return  (pawn_attacks(BLACK, s)   & pieces<PAWN>(WHITE))
+        | (pawn_attacks(WHITE, s)   & pieces<PAWN>(BLACK))
+        | (piece_attacks<KNIGHT>(s) & pieces<KNIGHT>())
+        | (piece_attacks<ROOK>(s)   & pieces<ROOK_AND_QUEEN>())
+        | (piece_attacks<BISHOP>(s) & pieces<BISHOP_AND_QUEEN>())
+        | (piece_attacks<KING>(s)   & pieces<KING>());
 }
 
 /// Position::piece_attacks_square() tests whether the piece on square f
@@ -435,8 +435,8 @@ bool Position::move_attacks_square(Move m, Square s) const {
   Color us = color_of_piece_on(f);
   clear_bit(&occ, f);
   set_bit(&occ, t);
-  Bitboard xray = ( (rook_attacks_bb(s, occ) & rooks_and_queens())
-                   |(bishop_attacks_bb(s, occ) & bishops_and_queens())) & pieces_of_color(us);
+  Bitboard xray = ( (rook_attacks_bb(s, occ) &  pieces<ROOK_AND_QUEEN>())
+                   |(bishop_attacks_bb(s, occ) & pieces<BISHOP_AND_QUEEN>())) & pieces_of_color(us);
 
   // If we have attacks we need to verify that are caused by our move
   // and are not already existent ones.
@@ -503,8 +503,8 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
       clear_bit(&b, capsq);
       set_bit(&b, to);
 
-      return   !(rook_attacks_bb(ksq, b) & rooks_and_queens(them))
-            && !(bishop_attacks_bb(ksq, b) & bishops_and_queens(them));
+      return   !(rook_attacks_bb(ksq, b) & pieces<ROOK_AND_QUEEN>(them))
+            && !(bishop_attacks_bb(ksq, b) & pieces<BISHOP_AND_QUEEN>(them));
   }
 
   // If the moving piece is a king, check whether the destination
@@ -586,8 +586,8 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const {
           clear_bit(&b, from);
           clear_bit(&b, capsq);
           set_bit(&b, to);
-          return  (rook_attacks_bb(ksq, b) & rooks_and_queens(us))
-                ||(bishop_attacks_bb(ksq, b) & bishops_and_queens(us));
+          return  (rook_attacks_bb(ksq, b) & pieces<ROOK_AND_QUEEN>(us))
+                ||(bishop_attacks_bb(ksq, b) & pieces<BISHOP_AND_QUEEN>(us));
       }
       return false;
 
@@ -674,10 +674,10 @@ inline void Position::update_checkers(Bitboard* pCheckersBB, Square ksq, Square
   if (Piece != QUEEN && bit_is_set(dcCandidates, from))
   {
       if (Piece != ROOK)
-          (*pCheckersBB) |= (piece_attacks<ROOK>(ksq) & rooks_and_queens(side_to_move()));
+          (*pCheckersBB) |= (piece_attacks<ROOK>(ksq) & pieces<ROOK_AND_QUEEN>(side_to_move()));
 
       if (Piece != BISHOP)
-          (*pCheckersBB) |= (piece_attacks<BISHOP>(ksq) & bishops_and_queens(side_to_move()));
+          (*pCheckersBB) |= (piece_attacks<BISHOP>(ksq) & pieces<BISHOP_AND_QUEEN>(side_to_move()));
   }
 }
 
@@ -806,7 +806,7 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) {
       // Set en passant square, only if moved pawn can be captured
       if (abs(int(to) - int(from)) == 16)
       {
-          if (pawn_attacks(us, from + (us == WHITE ? DELTA_N : DELTA_S)) & pawns(them))
+          if (pawn_attacks(us, from + (us == WHITE ? DELTA_N : DELTA_S)) & pieces<PAWN>(them))
           {
               st->epSquare = Square((int(from) + int(to)) / 2);
               key ^= zobEp[st->epSquare];
@@ -1366,12 +1366,12 @@ int Position::see(Square from, Square to) const {
   while (true)
   {
       clear_bit(&occ, from);
-      attackers =  (rook_attacks_bb(to, occ)   & rooks_and_queens())
-                 | (bishop_attacks_bb(to, occ) & bishops_and_queens())
-                 | (piece_attacks<KNIGHT>(to)  & knights())
-                 | (piece_attacks<KING>(to)    & kings())
-                 | (pawn_attacks(WHITE, to)    & pawns(BLACK))
-                 | (pawn_attacks(BLACK, to)    & pawns(WHITE));
+      attackers =  (rook_attacks_bb(to, occ)   & pieces<ROOK_AND_QUEEN>())
+                 | (bishop_attacks_bb(to, occ) & pieces<BISHOP_AND_QUEEN>())
+                 | (piece_attacks<KNIGHT>(to)  & pieces<KNIGHT>())
+                 | (piece_attacks<KING>(to)    & pieces<KING>())
+                 | (pawn_attacks(WHITE, to)    & pieces<PAWN>(BLACK))
+                 | (pawn_attacks(BLACK, to)    & pieces<PAWN>(WHITE));
 
       if (from != SQ_NONE)
           break;
@@ -1422,8 +1422,8 @@ int Position::see(Square from, Square to) const {
       // and scan for new X-ray attacks behind the attacker.
       b = stmAttackers & pieces_of_type(pt);
       occ ^= (b & (~b + 1));
-      attackers |=  (rook_attacks_bb(to, occ) & rooks_and_queens())
-                  | (bishop_attacks_bb(to, occ) & bishops_and_queens());
+      attackers |=  (rook_attacks_bb(to, occ) &  pieces<ROOK_AND_QUEEN>())
+                  | (bishop_attacks_bb(to, occ) & pieces<BISHOP_AND_QUEEN>());
 
       attackers &= occ;
 
@@ -1589,7 +1589,7 @@ Key Position::compute_pawn_key() const {
 
   for (Color c = WHITE; c <= BLACK; c++)
   {
-      b = pawns(c);
+      b = pieces<PAWN>(c);
       while(b)
       {
           s = pop_1st_bit(&b);
@@ -1679,7 +1679,7 @@ Value Position::compute_non_pawn_material(Color c) const {
 bool Position::is_draw() const {
 
   // Draw by material?
-  if (   !pawns()
+  if (   !pieces<PAWN>()
       && (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMidgame))
       return true;
 
index 16e72519f130ee01820423928c217585ace81f04..b3d0cd0a6c90e8c4358fa461ab876ae4b7071b4b 100644 (file)
@@ -163,24 +163,14 @@ public:
   Bitboard occupied_squares() const;
   Bitboard pieces_of_color(Color c) const;
   Bitboard pieces_of_type(PieceType pt) const;
-  Bitboard pawns() const;
-  Bitboard knights() const;
-  Bitboard bishops() const;
-  Bitboard rooks() const;
-  Bitboard queens() const;
-  Bitboard kings() const;
-  Bitboard rooks_and_queens() const;
-  Bitboard bishops_and_queens() const;
-  Bitboard sliders() const;
-  Bitboard pawns(Color c) const;
-  Bitboard knights(Color c) const;
-  Bitboard bishops(Color c) const;
-  Bitboard rooks(Color c) const;
-  Bitboard queens(Color c) const;
-  Bitboard kings(Color c) const;
-  Bitboard rooks_and_queens(Color c) const;
-  Bitboard bishops_and_queens(Color c) const;
-  Bitboard sliders_of_color(Color c) const;
+
+  // Pieces by constant type of both colors
+  template<PieceType Piece> Bitboard pieces()    const { return byTypeBB[Piece]; }
+  template<> Bitboard pieces<BISHOP_AND_QUEEN>() const { return byTypeBB[BISHOP] | byTypeBB[QUEEN]; }
+  template<> Bitboard pieces<ROOK_AND_QUEEN>()   const { return byTypeBB[ROOK]   | byTypeBB[QUEEN]; }
+
+  // Pieces by constant type of a given color
+  template<PieceType Piece> Bitboard pieces(Color c) const { return byColorBB[c] & pieces<Piece>(); }
 
   // Number of pieces of each color and type
   int piece_count(Color c, PieceType pt) const;
@@ -413,74 +403,6 @@ inline Bitboard Position::pieces_of_type(PieceType pt) const {
   return byTypeBB[pt];
 }
 
-inline Bitboard Position::pawns() const {
-  return pieces_of_type(PAWN);
-}
-
-inline Bitboard Position::knights() const {
-  return pieces_of_type(KNIGHT);
-}
-
-inline Bitboard Position::bishops() const {
-  return pieces_of_type(BISHOP);
-}
-
-inline Bitboard Position::rooks() const {
-  return pieces_of_type(ROOK);
-}
-
-inline Bitboard Position::queens() const {
-  return pieces_of_type(QUEEN);
-}
-
-inline Bitboard Position::kings() const {
-  return pieces_of_type(KING);
-}
-
-inline Bitboard Position::rooks_and_queens() const {
-  return rooks() | queens();
-}
-
-inline Bitboard Position::bishops_and_queens() const {
-  return bishops() | queens();
-}
-
-inline Bitboard Position::sliders() const {
-  return bishops() | queens() | rooks();
-}
-
-inline Bitboard Position::pawns(Color c) const {
-  return pieces_of_color(c) & pieces_of_type(PAWN);
-}
-
-inline Bitboard Position::knights(Color c) const {
-  return pieces_of_color(c) & pieces_of_type(KNIGHT);
-}
-
-inline Bitboard Position::bishops(Color c) const {
-  return pieces_of_color(c) & pieces_of_type(BISHOP);
-}
-
-inline Bitboard Position::rooks(Color c) const {
-  return pieces_of_color(c) & pieces_of_type(ROOK);
-}
-
-inline Bitboard Position::queens(Color c) const {
-  return pieces_of_color(c) & pieces_of_type(QUEEN);
-}
-
-inline Bitboard Position::kings(Color c) const {
-  return pieces_of_color(c) & pieces_of_type(KING);
-}
-
-inline Bitboard Position::rooks_and_queens(Color c) const {
-  return pieces_of_color(c) & rooks_and_queens();
-}
-
-inline Bitboard Position::bishops_and_queens(Color c) const {
-  return pieces_of_color(c) & bishops_and_queens();
-}
-
 inline int Position::piece_count(Color c, PieceType pt) const {
   return pieceCount[c][pt];
 }
@@ -559,7 +481,7 @@ inline bool Position::pawn_attacks_square(Color c, Square f, Square t) const {
 }
 
 template<PieceType Piece>
-Bitboard Position::piece_attacks_square(Square f, Square t) const {
+inline Bitboard Position::piece_attacks_square(Square f, Square t) const {
   return bit_is_set(piece_attacks<Piece>(f), t);
 }
 
@@ -574,7 +496,7 @@ inline bool Position::square_is_attacked(Square s, Color c) const {
 }
 
 inline bool Position::pawn_is_passed(Color c, Square s) const {
-  return !(pawns(opposite_color(c)) & passed_pawn_mask(c, s));
+  return !(pieces<PAWN>(opposite_color(c)) & passed_pawn_mask(c, s));
 }
 
 inline bool Position::pawn_is_passed(Bitboard theirPawns, Color c, Square s) {
@@ -590,7 +512,7 @@ inline bool Position::pawn_is_doubled(Bitboard ourPawns, Color c, Square s) {
 }
 
 inline bool Position::square_is_weak(Square s, Color c) const {
-  return !(pawns(c) & outpost_mask(opposite_color(c), s));
+  return !(pieces<PAWN>(c) & outpost_mask(opposite_color(c), s));
 }
 
 inline Key Position::get_key() const {
@@ -666,7 +588,7 @@ inline bool Position::opposite_colored_bishops() const {
 
 inline bool Position::has_pawn_on_7th(Color c) const {
 
-  return pawns(c) & relative_rank_bb(c, RANK_7);
+  return pieces<PAWN>(c) & relative_rank_bb(c, RANK_7);
 }
 
 inline bool Position::move_is_capture(Move m) const {