]> git.sesse.net Git - stockfish/blobdiff - src/evaluate.cpp
Micro optimize mobility calculation
[stockfish] / src / evaluate.cpp
index ba3ea9fb4def53ac2351033c3227d3cf7b1455f4..6ef8e18337e3507d6ee155b8e49970a2ae03a4b9 100644 (file)
@@ -309,6 +309,7 @@ Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) {
 
   assert(pos.is_ok());
   assert(threadID >= 0 && threadID < THREAD_MAX);
+  assert(!pos.is_check());
 
   memset(&ei, 0, sizeof(EvalInfo));
 
@@ -530,7 +531,7 @@ namespace {
   // evaluate_mobility() computes mobility and attacks for every piece
 
   template<PieceType Piece, Color Us, bool HasPopCnt>
-  int evaluate_mobility(const Position& pos, Bitboard b, EvalInfo& ei) {
+  int evaluate_mobility(const Position& pos, Bitboard b, Bitboard mob_area, EvalInfo& ei) {
 
     const Color Them = (Us == WHITE ? BLACK : WHITE);
     static const int AttackWeight[] = { 0, 0, KnightAttackWeight, BishopAttackWeight, RookAttackWeight, QueenAttackWeight };
@@ -551,13 +552,11 @@ namespace {
             ei.kingAdjacentZoneAttacksCount[Us] += count_1s_max_15<HasPopCnt>(bb);
     }
 
-    // Remove squares protected by enemy pawns or occupied by our pieces
-    b &= ~(ei.attackedBy[Them][PAWN] | pos.pieces_of_color(Us));
-
     // The squares occupied by enemy pieces (not defended by pawns) will be
     // counted two times instead of one. The shift (almost) guarantees that
     // intersection of the shifted value with b is zero so that after or-ing
     // the count of 1s bits is increased by the number of affected squares.
+    b &= mob_area;
     b |= Us == WHITE ? ((b & pos.pieces_of_color(Them)) >> 1)
                      : ((b & pos.pieces_of_color(Them)) << 1);
 
@@ -613,6 +612,9 @@ namespace {
     const Color Them = (Us == WHITE ? BLACK : WHITE);
     const Square* ptr = pos.piece_list_begin(Us, Piece);
 
+    // Do not include in mobility squares protected by enemy pawns or occupied by our pieces
+    const Bitboard mob_area = ~(ei.attackedBy[Them][PAWN] | pos.pieces_of_color(Us));
+
     while ((s = *ptr++) != SQ_NONE)
     {
         if (Piece == KNIGHT || Piece == QUEEN)
@@ -625,7 +627,7 @@ namespace {
             assert(false);
 
         // Attacks and mobility
-        mob = evaluate_mobility<Piece, Us, HasPopCnt>(pos, b, ei);
+        mob = evaluate_mobility<Piece, Us, HasPopCnt>(pos, b, mob_area, ei);
 
         // Bishop and knight outposts squares
         if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Them))
@@ -1068,7 +1070,10 @@ namespace {
             Square winnerQSq = relative_square(winnerSide, make_square(square_file(pawnToGo[winnerSide]), RANK_8));
             Square loserQSq = relative_square(loserSide, make_square(square_file(pawnToGo[loserSide]), RANK_8));
 
-            Bitboard b = pos.attacks_from<QUEEN>(winnerQSq);
+            Bitboard b = pos.occupied_squares();
+            clear_bit(&b, pawnToGo[winnerSide]);
+            clear_bit(&b, pawnToGo[loserSide]);
+            b = queen_attacks_bb(winnerQSq, b);
 
             if (  (b & pos.pieces(KING, loserSide))
                 ||(bit_is_set(b, loserQSq) && !bit_is_set(ei.attacked_by(loserSide), loserQSq)))