Use more_than_one() instead of single_bit()
authorMarco Costalba <mcostalba@gmail.com>
Sat, 14 Apr 2012 08:16:34 +0000 (09:16 +0100)
committerMarco Costalba <mcostalba@gmail.com>
Sat, 14 Apr 2012 08:51:59 +0000 (09:51 +0100)
It is more correct given what the function does. In
particular single_bit() returns true also in case of
empty bitboards.

Of course also the usual renaming while there :-)

No functional change.

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

index 40cdbb21ff956601238b0db0dc72176e5cb081cb..d0e4f51d7e4c55c7703814c4b4199f20fa55cbdf 100644 (file)
@@ -45,7 +45,7 @@ Bitboard ThisAndAdjacentFilesBB[8];
 Bitboard InFrontBB[2][8];
 Bitboard StepAttacksBB[16][64];
 Bitboard BetweenBB[64][64];
-Bitboard SquaresInFrontMask[2][64];
+Bitboard ForwardBB[2][64];
 Bitboard PassedPawnMask[2][64];
 Bitboard AttackSpanMask[2][64];
 Bitboard PseudoAttacks[6][64];
@@ -189,9 +189,9 @@ void Bitboards::init() {
   for (Color c = WHITE; c <= BLACK; c++)
       for (Square s = SQ_A1; s <= SQ_H8; s++)
       {
-          SquaresInFrontMask[c][s] = in_front_bb(c, s) & file_bb(s);
-          PassedPawnMask[c][s]     = in_front_bb(c, s) & this_and_adjacent_files_bb(file_of(s));
-          AttackSpanMask[c][s]     = in_front_bb(c, s) & adjacent_files_bb(file_of(s));
+          ForwardBB[c][s]      = in_front_bb(c, s) & file_bb(s);
+          PassedPawnMask[c][s] = in_front_bb(c, s) & this_and_adjacent_files_bb(file_of(s));
+          AttackSpanMask[c][s] = in_front_bb(c, s) & adjacent_files_bb(file_of(s));
       }
 
   for (Square s1 = SQ_A1; s1 <= SQ_H8; s1++)
index 294025b5266fb9f76aab1181a4ef3583ee8edf90..59b30a7f009204bb06b9b258a050797d96a362c0 100644 (file)
@@ -50,7 +50,7 @@ extern Bitboard ThisAndAdjacentFilesBB[8];
 extern Bitboard InFrontBB[2][8];
 extern Bitboard StepAttacksBB[16][64];
 extern Bitboard BetweenBB[64][64];
-extern Bitboard SquaresInFrontMask[2][64];
+extern Bitboard ForwardBB[2][64];
 extern Bitboard PassedPawnMask[2][64];
 extern Bitboard AttackSpanMask[2][64];
 extern Bitboard PseudoAttacks[6][64];
@@ -80,6 +80,13 @@ inline Bitboard operator^(Bitboard b, Square s) {
 }
 
 
+/// more_than_one() returns true if in 'b' there is more than one bit set
+
+inline bool more_than_one(Bitboard b) {
+  return b & (b - 1);
+}
+
+
 /// rank_bb() and file_bb() take a file or a square as input and return
 /// a bitboard representing all squares on the given file or rank.
 
@@ -131,48 +138,23 @@ inline Bitboard in_front_bb(Color c, Square s) {
 }
 
 
-/// Functions for computing sliding attack bitboards. Function attacks_bb() takes
-/// a square and a bitboard of occupied squares as input, and returns a bitboard
-/// representing all squares attacked by Pt (bishop or rook) on the given square.
-template<PieceType Pt>
-FORCE_INLINE unsigned magic_index(Square s, Bitboard occ) {
-
-  Bitboard* const Masks  = Pt == ROOK ? RMasks  : BMasks;
-  Bitboard* const Magics = Pt == ROOK ? RMagics : BMagics;
-  unsigned* const Shifts = Pt == ROOK ? RShifts : BShifts;
-
-  if (Is64Bit)
-      return unsigned(((occ & Masks[s]) * Magics[s]) >> Shifts[s]);
-
-  unsigned lo = unsigned(occ) & unsigned(Masks[s]);
-  unsigned hi = unsigned(occ >> 32) & unsigned(Masks[s] >> 32);
-  return (lo * unsigned(Magics[s]) ^ hi * unsigned(Magics[s] >> 32)) >> Shifts[s];
-}
-
-template<PieceType Pt>
-inline Bitboard attacks_bb(Square s, Bitboard occ) {
-  Bitboard** const Attacks = Pt == ROOK ? RAttacks : BAttacks;
-  return Attacks[s][magic_index<Pt>(s, occ)];
-}
-
-
-/// squares_between returns a bitboard representing all squares between
-/// two squares.  For instance, squares_between(SQ_C4, SQ_F7) returns a
-/// bitboard with the bits for square d5 and e6 set.  If s1 and s2 are not
-/// on the same line, file or diagonal, EmptyBoardBB is returned.
+/// between_bb returns a bitboard representing all squares between two squares.
+/// For instance, between_bb(SQ_C4, SQ_F7) returns a bitboard with the bits for
+/// square d5 and e6 set.  If s1 and s2 are not on the same line, file or diagonal,
+/// 0 is returned.
 
-inline Bitboard squares_between(Square s1, Square s2) {
+inline Bitboard between_bb(Square s1, Square s2) {
   return BetweenBB[s1][s2];
 }
 
 
-/// squares_in_front_of takes a color and a square as input, and returns a
-/// bitboard representing all squares along the line in front of the square,
-/// from the point of view of the given color. Definition of the table is:
-/// SquaresInFrontOf[c][s] = in_front_bb(c, s) & file_bb(s)
+/// forward_bb takes a color and a square as input, and returns a bitboard
+/// representing all squares along the line in front of the square, from the
+/// point of view of the given color. Definition of the table is:
+/// ForwardBB[c][s] = in_front_bb(c, s) & file_bb(s)
 
-inline Bitboard squares_in_front_of(Color c, Square s) {
-  return SquaresInFrontMask[c][s];
+inline Bitboard forward_bb(Color c, Square s) {
+  return ForwardBB[c][s];
 }
 
 
@@ -214,11 +196,28 @@ inline Bitboard same_color_squares(Square s) {
 }
 
 
-/// single_bit() returns true if in the 'b' bitboard is set a single bit (or if
-/// b == 0).
+/// Functions for computing sliding attack bitboards. Function attacks_bb() takes
+/// a square and a bitboard of occupied squares as input, and returns a bitboard
+/// representing all squares attacked by Pt (bishop or rook) on the given square.
+template<PieceType Pt>
+FORCE_INLINE unsigned magic_index(Square s, Bitboard occ) {
+
+  Bitboard* const Masks  = Pt == ROOK ? RMasks  : BMasks;
+  Bitboard* const Magics = Pt == ROOK ? RMagics : BMagics;
+  unsigned* const Shifts = Pt == ROOK ? RShifts : BShifts;
 
-inline bool single_bit(Bitboard b) {
-  return !(b & (b - 1));
+  if (Is64Bit)
+      return unsigned(((occ & Masks[s]) * Magics[s]) >> Shifts[s]);
+
+  unsigned lo = unsigned(occ) & unsigned(Masks[s]);
+  unsigned hi = unsigned(occ >> 32) & unsigned(Masks[s] >> 32);
+  return (lo * unsigned(Magics[s]) ^ hi * unsigned(Magics[s] >> 32)) >> Shifts[s];
+}
+
+template<PieceType Pt>
+inline Bitboard attacks_bb(Square s, Bitboard occ) {
+  Bitboard** const Attacks = Pt == ROOK ? RAttacks : BAttacks;
+  return Attacks[s][magic_index<Pt>(s, occ)];
 }
 
 
index 5e021f1132917aa36d397a1f090f71938c72cb99..fdc48cb49553f7c0add882369b4c5c695ec71324 100644 (file)
@@ -710,7 +710,7 @@ ScaleFactor Endgame<KBPKB>::operator()(const Position& pos) const {
           return SCALE_FACTOR_DRAW;
       else
       {
-          Bitboard path = squares_in_front_of(strongerSide, pawnSq);
+          Bitboard path = forward_bb(strongerSide, pawnSq);
 
           if (path & pos.pieces(KING, weakerSide))
               return SCALE_FACTOR_DRAW;
index d090f4042177a04cc9975552959930a75f183d9a..6f6141bafd37e0c3f0701376cd47f8a85523e107 100644 (file)
@@ -581,7 +581,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
 
             assert(b);
 
-            if (single_bit(b) && (b & pos.pieces(Them)))
+            if (!more_than_one(b) && (b & pos.pieces(Them)))
                 score += ThreatBonus[Piece][type_of(pos.piece_on(first_1(b)))];
         }
 
@@ -689,8 +689,8 @@ Value do_evaluate(const Position& pos, Value& margin) {
                       & ~ei.attackedBy[Them][0];
 
     if (undefendedMinors)
-        score += single_bit(undefendedMinors) ? UndefendedMinorPenalty
-                                              : UndefendedMinorPenalty * 2;
+        score += more_than_one(undefendedMinors) ? UndefendedMinorPenalty * 2
+                                                 : UndefendedMinorPenalty;
 
     // Enemy pieces not defended by a pawn and under our attack
     weakEnemies =  pos.pieces(Them)
@@ -896,14 +896,14 @@ Value do_evaluate(const Position& pos, Value& margin) {
             // If the pawn is free to advance, increase bonus
             if (pos.square_empty(blockSq))
             {
-                squaresToQueen = squares_in_front_of(Us, s);
+                squaresToQueen = forward_bb(Us, s);
                 defendedSquares = squaresToQueen & ei.attackedBy[Us][0];
 
                 // If there is an enemy rook or queen attacking the pawn from behind,
                 // add all X-ray attacks by the rook or queen. Otherwise consider only
                 // the squares in the pawn's path attacked or occupied by the enemy.
-                if (   (squares_in_front_of(Them, s) & pos.pieces(ROOK, QUEEN, Them))
-                    && (squares_in_front_of(Them, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<ROOK>(s)))
+                if (   (forward_bb(Them, s) & pos.pieces(ROOK, QUEEN, Them))
+                    && (forward_bb(Them, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<ROOK>(s)))
                     unsafeSquares = squaresToQueen;
                 else
                     unsafeSquares = squaresToQueen & (ei.attackedBy[Them][0] | pos.pieces(Them));
@@ -978,7 +978,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
         {
             s = pop_1st_bit(&b);
             queeningSquare = relative_square(c, make_square(file_of(s), RANK_8));
-            queeningPath = squares_in_front_of(c, s);
+            queeningPath = forward_bb(c, s);
 
             // Compute plies to queening and check direct advancement
             movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2);
@@ -1026,7 +1026,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
 
         // Check if (without even considering any obstacles) we're too far away or doubled
         if (   pliesToQueen[winnerSide] + 3 <= pliesToGo
-            || (squares_in_front_of(loserSide, s) & pos.pieces(PAWN, loserSide)))
+            || (forward_bb(loserSide, s) & pos.pieces(PAWN, loserSide)))
             candidates ^= s;
     }
 
@@ -1050,7 +1050,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
 
         // Generate list of blocking pawns and supporters
         supporters = adjacent_files_bb(file_of(s)) & candidates;
-        opposed = squares_in_front_of(loserSide, s) & pos.pieces(PAWN, winnerSide);
+        opposed = forward_bb(loserSide, s) & pos.pieces(PAWN, winnerSide);
         blockers = passed_pawn_mask(loserSide, s) & pos.pieces(PAWN, winnerSide);
 
         assert(blockers);
index 154e69e2207dc504c718050d310254cd9f880da0..4016ccb364cb22d2642993a1c96aa2ca56be6b62 100644 (file)
@@ -410,7 +410,7 @@ MoveStack* generate<MV_EVASION>(const Position& pos, MoveStack* mlist) {
           // If queen and king are far or not on a diagonal line we can safely
           // remove all the squares attacked in the other direction becuase are
           // not reachable by the king anyway.
-          if (squares_between(ksq, checksq) || !(PseudoAttacks[BISHOP][checksq] & ksq))
+          if (between_bb(ksq, checksq) || !(PseudoAttacks[BISHOP][checksq] & ksq))
               sliderAttacks |= PseudoAttacks[QUEEN][checksq];
 
           // Otherwise we need to use real rook attacks to check if king is safe
@@ -434,7 +434,7 @@ MoveStack* generate<MV_EVASION>(const Position& pos, MoveStack* mlist) {
       return mlist;
 
   // Blocking evasions or captures of the checking piece
-  target = squares_between(checksq, ksq) | checkers;
+  target = between_bb(checksq, ksq) | checkers;
 
   mlist = (us == WHITE ? generate_pawn_moves<WHITE, MV_EVASION>(pos, mlist, target)
                        : generate_pawn_moves<BLACK, MV_EVASION>(pos, mlist, target));
index 7fd4ac071490dea47b3dc812bf968cc0d15e94b9..6897969cb08398414470f902b839a9e67faec84b 100644 (file)
@@ -152,8 +152,8 @@ Score PawnTable::evaluate_pawns(const Position& pos, Bitboard ourPawns,
       // chain (but not the backward one).
       chain    =   ourPawns   & adjacent_files_bb(f) & b;
       isolated = !(ourPawns   & adjacent_files_bb(f));
-      doubled  =   ourPawns   & squares_in_front_of(Us, s);
-      opposed  =   theirPawns & squares_in_front_of(Us, s);
+      doubled  =   ourPawns   & forward_bb(Us, s);
+      opposed  =   theirPawns & forward_bb(Us, s);
       passed   = !(theirPawns & passed_pawn_mask(Us, s));
 
       // Test for backward pawn
index e5e0ab06d6eff97946b800ae8ff7bbf159cfa198..6458bb39d6d3703c80c52bb6ead08cfeb4fe1190 100644 (file)
@@ -364,9 +364,9 @@ Bitboard Position::hidden_checkers() const {
 
   while (pinners)
   {
-      b = squares_between(ksq, pop_1st_bit(&pinners)) & pieces();
+      b = between_bb(ksq, pop_1st_bit(&pinners)) & pieces();
 
-      if (b && single_bit(b) && (b & pieces(sideToMove)))
+      if (b && !more_than_one(b) && (b & pieces(sideToMove)))
           result |= b;
   }
   return result;
@@ -608,7 +608,7 @@ bool Position::is_pseudo_legal(const Move m) const {
               return false;
 
           // Our move must be a blocking evasion or a capture of the checking piece
-          if (!((squares_between(checksq, king_square(us)) | checkers()) & to))
+          if (!((between_bb(checksq, king_square(us)) | checkers()) & to))
               return false;
       }
       // In case of king moves under check we have to remove king so to catch
index b38b7bab92ef84df92eb625b3316b496280a8dcf..08a157c2c793235c7977063ad29bc5118cd19e40 100644 (file)
@@ -1337,7 +1337,7 @@ split_point_start: // At split points actual search starts from here
     // Rule 1. Checks which give opponent's king at most one escape square are dangerous
     b = kingAtt & ~pos.pieces(them) & ~newAtt & ~(1ULL << to);
 
-    if (single_bit(b)) // Catches also !b
+    if (!more_than_one(b))
         return true;
 
     // Rule 2. Queen contact check is very dangerous
@@ -1386,7 +1386,7 @@ split_point_start: // At split points actual search starts from here
 
     // Case 3: Moving through the vacated square
     p2 = pos.piece_on(f2);
-    if (piece_is_slider(p2) && (squares_between(f2, t2) & f1))
+    if (piece_is_slider(p2) && (between_bb(f2, t2) & f1))
       return true;
 
     // Case 4: The destination square for m2 is defended by the moving piece in m1
@@ -1397,7 +1397,7 @@ split_point_start: // At split points actual search starts from here
     // Case 5: Discovered check, checking piece is the piece moved in m1
     ksq = pos.king_square(pos.side_to_move());
     if (    piece_is_slider(p1)
-        && (squares_between(t1, ksq) & f2)
+        && (between_bb(t1, ksq) & f2)
         && (pos.attacks_from(p1, t1, pos.pieces() ^ f2) & ksq))
         return true;
 
@@ -1469,7 +1469,7 @@ split_point_start: // At split points actual search starts from here
     // Case 3: If the moving piece in the threatened move is a slider, don't
     // prune safe moves which block its ray.
     if (    piece_is_slider(pos.piece_on(tfrom))
-        && (squares_between(tfrom, tto) & mto)
+        && (between_bb(tfrom, tto) & mto)
         &&  pos.see_sign(m) >= 0)
         return true;
 
@@ -1873,7 +1873,7 @@ void Thread::idle_loop(SplitPoint* sp_master) {
                   &&  spCnt > 0
                   && !latest->cutoff
                   &&  latest->slavesMask == latest->allSlavesMask
-                  && !single_bit(latest->allSlavesMask))
+                  &&  more_than_one(latest->allSlavesMask))
               {
                   lock_grab(latest->lock);
                   lock_grab(Threads.splitLock);
@@ -1884,7 +1884,7 @@ void Thread::idle_loop(SplitPoint* sp_master) {
                       &&  spCnt == th->splitPointsCnt
                       && !latest->cutoff
                       &&  latest->slavesMask == latest->allSlavesMask
-                      && !single_bit(latest->allSlavesMask))
+                      &&  more_than_one(latest->allSlavesMask))
                   {
                       latest->slavesMask |= 1ULL << idx; // allSlavesMask is not updated
                       curSplitPoint = latest;