Second take at unifying bitboard representation access
authorMarco Costalba <mcostalba@gmail.com>
Wed, 2 Sep 2009 09:57:38 +0000 (11:57 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Fri, 4 Sep 2009 07:21:06 +0000 (08:21 +0100)
This patch is built on Tord idea to use functions instead of
templates to access position's bitboards. This has the added advantage
that we don't need fallback functions for cases where the piece
type or the color is a variable and not a constant.

Also added Joona suggestion to workaround request for two types
of pieces like bishop_and_queens() and rook_and_queens().

No functionality or 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 69d0df5114463f86119e0dfc1e4bd704aba0a2e5..882c07cbf43d7c9ec3d08218920408c3509f7e07 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.pieces<PAWN>() == 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.pieces<PAWN>(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.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)))
+      && (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.pieces<PAWN>(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.pieces<PAWN>(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.pieces<KING>(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.pieces<BISHOP>(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.pieces<BISHOP>(weakerSide))))
+                 || (pos.piece_attacks<BISHOP>(blockSq1) & pos.pieces(BISHOP, weakerSide))))
         return ScaleFactor(0);
     else
         return SCALE_FACTOR_NONE;
index a1015edfa3d89bf399631e44bcf2a6bf61a9b0ba..7fbe9af5092a92f04e2c5f6a7053cfa46f30ba84 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.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);
+  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.pieces<PAWN>(us)))
+    if (bonus && (p.pawn_attacks(them, s) & p.pieces(PAWN, us)))
     {
-        if (    p.pieces<KNIGHT>(them) == EmptyBoardBB
-            && (SquaresByColorBB[square_color(s)] & p.pieces<BISHOP>(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.pieces<QUEEN>(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.pieces<ROOK_AND_QUEEN>(us));
+            b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, 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.pieces<ROOK_AND_QUEEN>(us))
-                            && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces<BISHOP_AND_QUEEN>(us)))
+                            && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces(ROOK, QUEEN, us))
+                            && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & p.pieces(BISHOP, 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.pieces<PAWN>();
+        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.pieces<PAWN>(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.pieces<ROOK_AND_QUEEN>(them)))
+                        && (squares_behind(us, s) & pos.pieces(ROOK, 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<PAWN>(them)) == 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.pieces<PAWN>(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.pieces<ROOK_AND_QUEEN>(them))
+                else if (pos.pieces(ROOK, 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.pieces<PAWN>(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.pieces<PAWN>(us);
+    Bitboard behindFriendlyPawns = pos.pieces(PAWN, us);
     if (us == WHITE)
     {
         behindFriendlyPawns |= (behindFriendlyPawns >> 8);
index 9a20292bd010fda49a36b7ff3e060109eda749f5..a3d9f7c8a73958ca7c8235e6f62c81ec85479d58 100644 (file)
@@ -171,14 +171,14 @@ MaterialInfo* MaterialInfoTable::get_material_info(const Position& pos) {
       mi->evaluationFunction = &EvaluateKKX;
       return mi;
   }
-  else if (   pos.pieces<PAWN>() == EmptyBoardBB
-           && pos.pieces<ROOK>() == EmptyBoardBB
-           && pos.pieces<QUEEN>() == 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.pieces<KNIGHT>(WHITE) | pos.pieces<BISHOP>(WHITE)));
-      assert((pos.pieces<KNIGHT>(BLACK) | pos.pieces<BISHOP>(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 41f5b077f9468ba9c1181a82332542cbf799774e..0b052e5bb105dd822e771c4ba3f098164ae84bd4 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.pieces<BISHOP_AND_QUEEN>();
+  Bitboard b = checkers & pos.pieces(BISHOP, QUEEN);
   while (b)
   {
       from = pop_1st_bit(&b);
       checkersAttacks |= bishop_attacks_bb(from, b_noKing);
   }
 
-  b = checkers & pos.pieces<ROOK_AND_QUEEN>();
+  b = checkers & pos.pieces(ROOK, 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.pieces<PAWN>(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.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;
+      b1 = (  (pos.piece_attacks<KNIGHT>(checksq) & pos.pieces(KNIGHT, us))
+            | (pos.piece_attacks<BISHOP>(checksq) & pos.pieces(BISHOP, QUEEN, us))
+            | (pos.piece_attacks<ROOK>(checksq)   & pos.pieces(ROOK, 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.pieces<BISHOP>() | pos.pieces<ROOK>() | pos.pieces<QUEEN>()))
+      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.pieces<PAWN>(them)))
+      if (pos.ep_square() != SQ_NONE && (checkers & pos.pieces(PAWN, them)))
       {
           to = pos.ep_square();
-          b1 = pos.pawn_attacks(them, to) & pos.pieces<PAWN>(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.pieces<PAWN>(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.pieces<PAWN>(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.pieces<PAWN>(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<Piece>(us);
+    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.pieces<PAWN>(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 1d8b082ed449cb55281054b156721ba79deeaf42..71b1738cc253f8b3b5bafc215d7d160ea71c8c01 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.pieces<PAWN>(us);
-    Bitboard theirPawns = pos.pieces<PAWN>(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.pieces<PAWN>(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 5b93ea7dc0b97785894843b32787b7d72a874717..48e26c3962edfd0791d07d6cf382efb304d3c4fd 100644 (file)
@@ -35,8 +35,7 @@
 
 enum PieceType {
   NO_PIECE_TYPE = 0,
-  PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6,
-  BISHOP_AND_QUEEN = 8, ROOK_AND_QUEEN = 9
+  PAWN = 1, KNIGHT = 2, BISHOP = 3, ROOK = 4, QUEEN = 5, KING = 6
 };
 
 enum Piece {
index aa07cd51cf501abc9a6dd79593de9fb49787e576..770d47f5d17026ef0e0d0f53c7dabfcc502b4354 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 =  (pieces<ROOK_AND_QUEEN>(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq])
-           | (pieces<BISHOP_AND_QUEEN>(FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq]);
+  pinners =  (pieces(ROOK, QUEEN, FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq])
+           | (pieces(BISHOP, 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)   & 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>());
+  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, QUEEN))
+        | (piece_attacks<BISHOP>(s) & pieces(BISHOP, 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) &  pieces<ROOK_AND_QUEEN>())
-                   |(bishop_attacks_bb(s, occ) & pieces<BISHOP_AND_QUEEN>())) & pieces_of_color(us);
+  Bitboard xray = ( (rook_attacks_bb(s, occ) &  pieces(ROOK, QUEEN))
+                   |(bishop_attacks_bb(s, occ) & pieces(BISHOP, 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) & pieces<ROOK_AND_QUEEN>(them))
-            && !(bishop_attacks_bb(ksq, b) & pieces<BISHOP_AND_QUEEN>(them));
+      return   !(rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, them))
+            && !(bishop_attacks_bb(ksq, b) & pieces(BISHOP, 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) & pieces<ROOK_AND_QUEEN>(us))
-                ||(bishop_attacks_bb(ksq, b) & pieces<BISHOP_AND_QUEEN>(us));
+          return  (rook_attacks_bb(ksq, b) & pieces(ROOK, QUEEN, us))
+                ||(bishop_attacks_bb(ksq, b) & pieces(BISHOP, 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) & pieces<ROOK_AND_QUEEN>(side_to_move()));
+          (*pCheckersBB) |= (piece_attacks<ROOK>(ksq) & pieces(ROOK, QUEEN, side_to_move()));
 
       if (Piece != BISHOP)
-          (*pCheckersBB) |= (piece_attacks<BISHOP>(ksq) & pieces<BISHOP_AND_QUEEN>(side_to_move()));
+          (*pCheckersBB) |= (piece_attacks<BISHOP>(ksq) & pieces(BISHOP, 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)) & pieces<PAWN>(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)   & 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));
+      attackers =  (rook_attacks_bb(to, occ)   & pieces(ROOK, QUEEN))
+                 | (bishop_attacks_bb(to, occ) & pieces(BISHOP, 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;
@@ -1384,10 +1384,10 @@ int Position::see(Square from, Square to) const {
       // and use it to initialize from square.
       stmAttackers = attackers & pieces_of_color(us);
       PieceType pt;
-      for (pt = PAWN; !(stmAttackers & pieces_of_type(pt)); pt++)
+      for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
           assert(pt < KING);
 
-      from = first_1(stmAttackers & pieces_of_type(pt));
+      from = first_1(stmAttackers & pieces(pt));
       piece = piece_on(from);
   }
 
@@ -1415,15 +1415,15 @@ int Position::see(Square from, Square to) const {
       // Locate the least valuable attacker for the side to move. The loop
       // below looks like it is potentially infinite, but it isn't. We know
       // that the side to move still has at least one attacker left.
-      for (pt = PAWN; !(stmAttackers & pieces_of_type(pt)); pt++)
+      for (pt = PAWN; !(stmAttackers & pieces(pt)); pt++)
           assert(pt < KING);
 
       // Remove the attacker we just found from the 'attackers' bitboard,
       // and scan for new X-ray attacks behind the attacker.
-      b = stmAttackers & pieces_of_type(pt);
+      b = stmAttackers & pieces(pt);
       occ ^= (b & (~b + 1));
-      attackers |=  (rook_attacks_bb(to, occ) &  pieces<ROOK_AND_QUEEN>())
-                  | (bishop_attacks_bb(to, occ) & pieces<BISHOP_AND_QUEEN>());
+      attackers |=  (rook_attacks_bb(to, occ) &  pieces(ROOK, QUEEN))
+                  | (bishop_attacks_bb(to, occ) & pieces(BISHOP, QUEEN));
 
       attackers &= occ;
 
@@ -1589,7 +1589,7 @@ Key Position::compute_pawn_key() const {
 
   for (Color c = WHITE; c <= BLACK; c++)
   {
-      b = pieces<PAWN>(c);
+      b = pieces(PAWN, c);
       while(b)
       {
           s = pop_1st_bit(&b);
@@ -1634,7 +1634,7 @@ Value Position::compute_value() const {
   for (Color c = WHITE; c <= BLACK; c++)
       for (PieceType pt = PAWN; pt <= KING; pt++)
       {
-          b = pieces_of_color(c) & pieces_of_type(pt);
+          b = pieces(pt, c);
           while(b)
           {
               s = pop_1st_bit(&b);
@@ -1660,7 +1660,7 @@ Value Position::compute_non_pawn_material(Color c) const {
 
   for (PieceType pt = KNIGHT; pt <= QUEEN; pt++)
   {
-      Bitboard b = pieces_of_color(c) & pieces_of_type(pt);
+      Bitboard b = pieces(pt, c);
       while (b)
       {
           assert(piece_on(first_1(b)) == piece_of_color_and_type(c, pt));
@@ -1679,7 +1679,7 @@ Value Position::compute_non_pawn_material(Color c) const {
 bool Position::is_draw() const {
 
   // Draw by material?
-  if (   !pieces<PAWN>()
+  if (   !pieces(PAWN)
       && (non_pawn_material(WHITE) + non_pawn_material(BLACK) <= BishopValueMidgame))
       return true;
 
@@ -1956,7 +1956,7 @@ bool Position::is_ok(int* failedStep) const {
       // Separate piece type bitboards must have empty intersections
       for (PieceType p1 = PAWN; p1 <= KING; p1++)
           for (PieceType p2 = PAWN; p2 <= KING; p2++)
-              if (p1 != p2 && (pieces_of_type(p1) & pieces_of_type(p2)))
+              if (p1 != p2 && (pieces(p1) & pieces(p2)))
                   return false;
   }
 
@@ -2012,7 +2012,7 @@ bool Position::is_ok(int* failedStep) const {
   if (debugPieceCounts)
       for (Color c = WHITE; c <= BLACK; c++)
           for (PieceType pt = PAWN; pt <= KING; pt++)
-              if (pieceCount[c][pt] != count_1s(pieces_of_color(c) & pieces_of_type(pt)))
+              if (pieceCount[c][pt] != count_1s(pieces(pt, c)))
                   return false;
 
   if (failedStep) (*failedStep)++;
@@ -2022,7 +2022,7 @@ bool Position::is_ok(int* failedStep) const {
           for(PieceType pt = PAWN; pt <= KING; pt++)
               for(int i = 0; i < pieceCount[c][pt]; i++)
               {
-                  if (piece_on(piece_list(c, pt, i)) != (pieces_of_color(c) & pieces_of_type(pt)))
+                  if (piece_on(piece_list(c, pt, i)) != (pieces(pt, c)))
                       return false;
 
                   if (index[piece_list(c, pt, i)] != i)
index b3d0cd0a6c90e8c4358fa461ab876ae4b7071b4b..0006fbc772ca267e825d781c458e30ee28409c71 100644 (file)
@@ -162,15 +162,10 @@ public:
   Bitboard empty_squares() const;
   Bitboard occupied_squares() const;
   Bitboard pieces_of_color(Color c) const;
-  Bitboard pieces_of_type(PieceType pt) 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>(); }
+  Bitboard pieces(PieceType pt) const;
+  Bitboard pieces(PieceType pt, Color c) const;
+  Bitboard pieces(PieceType pt1, PieceType pt2) const;
+  Bitboard pieces(PieceType pt1, PieceType pt2, Color c) const;
 
   // Number of pieces of each color and type
   int piece_count(Color c, PieceType pt) const;
@@ -399,10 +394,22 @@ inline Bitboard Position::pieces_of_color(Color c) const {
   return byColorBB[c];
 }
 
-inline Bitboard Position::pieces_of_type(PieceType pt) const {
+inline Bitboard Position::pieces(PieceType pt) const {
   return byTypeBB[pt];
 }
 
+inline Bitboard Position::pieces(PieceType pt, Color c) const {
+  return byTypeBB[pt] & byColorBB[c];
+}
+
+inline Bitboard Position::pieces(PieceType pt1, PieceType pt2) const {
+  return byTypeBB[pt1] | byTypeBB[pt2];
+}
+
+inline Bitboard Position::pieces(PieceType pt1, PieceType pt2, Color c) const {
+  return (byTypeBB[pt1] | byTypeBB[pt2]) & byColorBB[c];
+}
+
 inline int Position::piece_count(Color c, PieceType pt) const {
   return pieceCount[c][pt];
 }
@@ -496,7 +503,7 @@ inline bool Position::square_is_attacked(Square s, Color c) const {
 }
 
 inline bool Position::pawn_is_passed(Color c, Square s) const {
-  return !(pieces<PAWN>(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) {
@@ -512,7 +519,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 !(pieces<PAWN>(c) & outpost_mask(opposite_color(c), s));
+  return !(pieces(PAWN, c) & outpost_mask(opposite_color(c), s));
 }
 
 inline Key Position::get_key() const {
@@ -588,7 +595,7 @@ inline bool Position::opposite_colored_bishops() const {
 
 inline bool Position::has_pawn_on_7th(Color c) const {
 
-  return pieces<PAWN>(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 {