]> git.sesse.net Git - stockfish/blobdiff - src/evaluate.cpp
Restrict queen mobility to safe squares
[stockfish] / src / evaluate.cpp
index b4e86f3b1d826030f8e6a3d4a34686d680a6f339..e96e635c876f44901a456b41189c98eddbcb85e9 100644 (file)
@@ -119,8 +119,8 @@ namespace {
     { S(-17,-33), S(-11,-16), S(-5,  0), S( 1, 16), S( 7, 32), S(13, 48), // Rooks
       S( 18, 64), S( 22, 80), S(26, 96), S(29,109), S(31,115), S(33,119),
       S( 35,122), S( 36,123), S(37,124) },
-    { S(-12,-20), S( -8,-13), S(-5, -7), S(-2, -1), S( 1,  5), S( 4, 11), // Queens
-      S(  7, 17), S( 10, 23), S(13, 29), S(16, 34), S(18, 38), S(20, 40),
+    { S(-12,-20), S( -8,-13), S(-5, -7), S( 0,  0), S( 6, 10), S(11, 19), // Queens
+      S( 13, 29), S( 18, 38), S(20, 40), S(21, 41), S(22, 41), S(22, 41),
       S( 22, 41), S( 23, 41), S(24, 41), S(25, 41), S(25, 41), S(25, 41),
       S( 25, 41), S( 25, 41), S(25, 41), S(25, 41), S(25, 41), S(25, 41),
       S( 25, 41), S( 25, 41), S(25, 41), S(25, 41) }
@@ -162,9 +162,7 @@ namespace {
 
   const Score Tempo            = make_score(24, 11);
   const Score RookOn7th        = make_score(11, 20);
-  const Score QueenOn7th       = make_score( 3,  8);
   const Score RookOnPawn       = make_score(10, 28);
-  const Score QueenOnPawn      = make_score( 4, 20);
   const Score RookOpenFile     = make_score(43, 21);
   const Score RookSemiopenFile = make_score(19, 10);
   const Score BishopPawns      = make_score( 8, 12);
@@ -215,7 +213,7 @@ namespace {
   template<Color Us>
   void init_eval_info(const Position& pos, EvalInfo& ei);
 
-  template<Color Us, bool Trace>
+  template<bool Trace>
   Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility);
 
   template<Color Us, bool Trace>
@@ -319,8 +317,7 @@ Value do_evaluate(const Position& pos) {
   init_eval_info<BLACK>(pos, ei);
 
   // Evaluate pieces and mobility
-  score +=  evaluate_pieces<WHITE, Trace>(pos, ei, mobility)
-          - evaluate_pieces<BLACK, Trace>(pos, ei, mobility);
+  score += evaluate_pieces<Trace>(pos, ei, mobility);
 
   score += apply_weight(mobility[WHITE] - mobility[BLACK], Weights[Mobility]);
 
@@ -484,6 +481,11 @@ Value do_evaluate(const Position& pos) {
                 ei.kingAdjacentZoneAttacksCount[Us] += popcount<Max15>(bb);
         }
 
+        if (Pt == QUEEN)
+            b &= ~(  ei.attackedBy[Them][KNIGHT]
+                   | ei.attackedBy[Them][BISHOP]
+                   | ei.attackedBy[Them][ROOK]);
+
         int mob = Pt != QUEEN ? popcount<Max15>(b & mobilityArea)
                               : popcount<Full >(b & mobilityArea);
 
@@ -514,23 +516,21 @@ Value do_evaluate(const Position& pos) {
                 score += MinorBehindPawn;
         }
 
-        if (  (Pt == ROOK || Pt == QUEEN)
-            && relative_rank(Us, s) >= RANK_5)
+        if (Pt == ROOK)
         {
-            // Major piece on 7th rank and enemy king trapped on 8th
+            // Rook on 7th rank and enemy king trapped on 8th
             if (   relative_rank(Us, s) == RANK_7
                 && relative_rank(Us, pos.king_square(Them)) == RANK_8)
-                score += Pt == ROOK ? RookOn7th : QueenOn7th;
+                score += RookOn7th;
 
-            // Major piece attacking enemy pawns on the same rank/file
-            Bitboard pawns = pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s];
-            if (pawns)
-                score += popcount<Max15>(pawns) * (Pt == ROOK ? RookOnPawn : QueenOnPawn);
-        }
+            // Rook piece attacking enemy pawns on the same rank/file
+            if (relative_rank(Us, s) >= RANK_5)
+            {
+                Bitboard pawns = pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s];
+                if (pawns)
+                    score += popcount<Max15>(pawns) * RookOnPawn;
+            }
 
-        // Special extra evaluation for rooks
-        if (Pt == ROOK)
-        {
             // Give a bonus for a rook on a open or semi-open file
             if (ei.pi->semiopen(Us, file_of(s)))
                 score += ei.pi->semiopen(Them, file_of(s)) ? RookOpenFile : RookSemiopenFile;
@@ -570,28 +570,39 @@ Value do_evaluate(const Position& pos) {
   }
 
 
-  // evaluate_pieces() assigns bonuses and penalties to all the
-  // pieces of a given color.
+  // evaluate_pieces() assigns bonuses and penalties to all the pieces of both colors
 
-  template<Color Us, bool Trace>
+  template<bool Trace>
   Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility) {
 
-    const Color Them = (Us == WHITE ? BLACK : WHITE);
-
     // Do not include in mobility squares protected by enemy pawns or occupied by our pieces
-    const Bitboard mobilityArea = ~(ei.attackedBy[Them][PAWN] | pos.pieces(Us, PAWN, KING));
+    const Bitboard whiteMobilityArea = ~(ei.attackedBy[BLACK][PAWN] | pos.pieces(WHITE, PAWN, KING));
+    const Bitboard blackMobilityArea = ~(ei.attackedBy[WHITE][PAWN] | pos.pieces(BLACK, PAWN, KING));
 
-    Score score =  evaluate_pieces<KNIGHT, Us, Trace>(pos, ei, mobility, mobilityArea)
-                 + evaluate_pieces<BISHOP, Us, Trace>(pos, ei, mobility, mobilityArea)
-                 + evaluate_pieces<ROOK,   Us, Trace>(pos, ei, mobility, mobilityArea)
-                 + evaluate_pieces<QUEEN,  Us, Trace>(pos, ei, mobility, mobilityArea);
+    Score score;
+
+    score  =  evaluate_pieces<KNIGHT, WHITE, Trace>(pos, ei, mobility, whiteMobilityArea)
+            - evaluate_pieces<KNIGHT, BLACK, Trace>(pos, ei, mobility, blackMobilityArea);
+    score +=  evaluate_pieces<BISHOP, WHITE, Trace>(pos, ei, mobility, whiteMobilityArea)
+            - evaluate_pieces<BISHOP, BLACK, Trace>(pos, ei, mobility, blackMobilityArea);
+    score +=  evaluate_pieces<  ROOK, WHITE, Trace>(pos, ei, mobility, whiteMobilityArea)
+            - evaluate_pieces<  ROOK, BLACK, Trace>(pos, ei, mobility, blackMobilityArea);
+    score +=  evaluate_pieces< QUEEN, WHITE, Trace>(pos, ei, mobility, whiteMobilityArea)
+            - evaluate_pieces< QUEEN, BLACK, Trace>(pos, ei, mobility, blackMobilityArea);
 
     // Sum up all attacked squares (updated in evaluate_pieces)
-    ei.attackedBy[Us][ALL_PIECES] =  ei.attackedBy[Us][PAWN]   | ei.attackedBy[Us][KNIGHT]
-                                   | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK]
-                                   | ei.attackedBy[Us][QUEEN]  | ei.attackedBy[Us][KING];
+    ei.attackedBy[WHITE][ALL_PIECES] =  ei.attackedBy[WHITE][PAWN]   | ei.attackedBy[WHITE][KNIGHT]
+                                      | ei.attackedBy[WHITE][BISHOP] | ei.attackedBy[WHITE][ROOK]
+                                      | ei.attackedBy[WHITE][QUEEN]  | ei.attackedBy[WHITE][KING];
+
+    ei.attackedBy[BLACK][ALL_PIECES] =  ei.attackedBy[BLACK][PAWN]   | ei.attackedBy[BLACK][KNIGHT]
+                                      | ei.attackedBy[BLACK][BISHOP] | ei.attackedBy[BLACK][ROOK]
+                                      | ei.attackedBy[BLACK][QUEEN]  | ei.attackedBy[BLACK][KING];
     if (Trace)
-        Tracing::terms[Us][Tracing::MOBILITY] = apply_weight(mobility[Us], Weights[Mobility]);
+    {
+        Tracing::terms[WHITE][Tracing::MOBILITY] = apply_weight(mobility[WHITE], Weights[Mobility]);
+        Tracing::terms[BLACK][Tracing::MOBILITY] = apply_weight(mobility[BLACK], Weights[Mobility]);
+    }
 
     return score;
   }
@@ -943,7 +954,7 @@ Value do_evaluate(const Position& pos) {
 
   // Tracing function definitions
 
-  double Tracing::to_cp(Value v) { return double(v) / PawnValueMg; }
+  double Tracing::to_cp(Value v) { return double(v) / PawnValueEg; }
 
   void Tracing::add_term(int idx, Score wScore, Score bScore) {