]> git.sesse.net Git - stockfish/blobdiff - src/evaluate.cpp
No need to test for MOVE_NONE before move_is_ok()
[stockfish] / src / evaluate.cpp
index 05c4c1119bb61eb0a6242c3072509a95cac9c14b..1bbc0a36eb7f12e1b043b3dace6d5aa986d75363 100644 (file)
@@ -75,7 +75,7 @@ namespace {
   const int GrainSize = 8;
 
   // Evaluation weights, initialized from UCI options
-  enum { Mobility, PawnStructure, PassedPawns, Space, KingDangerUs, KingDangerThem };
+  enum { Mobility, PassedPawns, Space, KingDangerUs, KingDangerThem };
   Score Weights[6];
 
   typedef Value V;
@@ -88,7 +88,7 @@ namespace {
   //
   // Values modified by Joona Kiiski
   const Score WeightsInternal[] = {
-      S(248, 271), S(233, 201), S(252, 259), S(46, 0), S(247, 0), S(259, 0)
+      S(248, 271), S(252, 259), S(46, 0), S(247, 0), S(259, 0)
   };
 
   // MobilityBonus[PieceType][attacked] contains mobility bonuses for middle and
@@ -142,9 +142,9 @@ namespace {
     { S(0, 0), S(15, 39), S(15, 39), S(15, 39), S(15, 39), S( 0,  0) }  // QUEEN
   };
 
-  // ThreatedByPawnPenalty[PieceType] contains a penalty according to which
+  // ThreatenedByPawnPenalty[PieceType] contains a penalty according to which
   // piece type is attacked by an enemy pawn.
-  const Score ThreatedByPawnPenalty[] = {
+  const Score ThreatenedByPawnPenalty[] = {
     S(0, 0), S(0, 0), S(56, 70), S(56, 70), S(76, 99), S(86, 118)
   };
 
@@ -275,7 +275,6 @@ Value do_evaluate(const Position& pos, Value& margin) {
   Value margins[2];
   Score score, mobilityWhite, mobilityBlack;
 
-  assert(pos.is_ok());
   assert(pos.thread() >= 0 && pos.thread() < MAX_THREADS);
   assert(!pos.in_check());
 
@@ -301,7 +300,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
 
   // Probe the pawn hash table
   ei.pi = Threads[pos.thread()].pawnTable.get_pawn_info(pos);
-  score += apply_weight(ei.pi->pawns_value(), Weights[PawnStructure]);
+  score += ei.pi->pawns_value();
 
   // Initialize attack and king safety bitboards
   init_eval_info<WHITE, HasPopCnt>(pos, ei);
@@ -371,7 +370,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
   {
       trace_add(PST, pos.value());
       trace_add(IMBALANCE, ei.mi->material_value());
-      trace_add(PAWN, apply_weight(ei.pi->pawns_value(), Weights[PawnStructure]));
+      trace_add(PAWN, ei.pi->pawns_value());
       trace_add(MOBILITY, apply_weight(mobilityWhite, Weights[Mobility]), apply_weight(mobilityBlack, Weights[Mobility]));
       trace_add(THREAT, evaluate_threats<WHITE>(pos, ei), evaluate_threats<BLACK>(pos, ei));
       trace_add(PASSED, evaluate_passed_pawns<WHITE>(pos, ei), evaluate_passed_pawns<BLACK>(pos, ei));
@@ -405,7 +404,6 @@ void read_evaluation_uci_options(Color us) {
   const int kingDangerThem = (us == WHITE ? KingDangerThem : KingDangerUs);
 
   Weights[Mobility]       = weight_option("Mobility (Middle Game)", "Mobility (Endgame)", WeightsInternal[Mobility]);
-  Weights[PawnStructure]  = weight_option("Pawn Structure (Middle Game)", "Pawn Structure (Endgame)", WeightsInternal[PawnStructure]);
   Weights[PassedPawns]    = weight_option("Passed Pawns (Middle Game)", "Passed Pawns (Endgame)", WeightsInternal[PassedPawns]);
   Weights[Space]          = weight_option("Space", "Space", WeightsInternal[Space]);
   Weights[kingDangerUs]   = weight_option("Cowardice", "Cowardice", WeightsInternal[KingDangerUs]);
@@ -487,11 +485,11 @@ namespace {
     const BitCountType Full  = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64 : CNT32;
     const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
     const Color Them = (Us == WHITE ? BLACK : WHITE);
-    const Square* ptr = pos.piece_list_begin(Us, Piece);
+    const Square* pl = pos.piece_list(Us, Piece);
 
     ei.attackedBy[Us][Piece] = EmptyBoardBB;
 
-    while ((s = *ptr++) != SQ_NONE)
+    while ((s = *pl++) != SQ_NONE)
     {
         // Find attacked squares, including x-ray attacks for bishops and rooks
         if (Piece == KNIGHT || Piece == QUEEN)
@@ -525,10 +523,11 @@ namespace {
         // Decrease score if we are attacked by an enemy pawn. Remaining part
         // of threat evaluation must be done later when we have full attack info.
         if (bit_is_set(ei.attackedBy[Them][PAWN], s))
-            score -= ThreatedByPawnPenalty[Piece];
+            score -= ThreatenedByPawnPenalty[Piece];
 
         // Bishop and knight outposts squares
-        if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Us))
+        if (    (Piece == BISHOP || Piece == KNIGHT)
+            && !(pos.pieces(PAWN, Them) & attack_span_mask(Us, s)))
             score += evaluate_outposts<Piece, Us>(pos, ei, s);
 
         // Queen or rook on 7th rank
@@ -620,7 +619,7 @@ namespace {
     Score score = SCORE_ZERO;
 
     // Enemy pieces not defended by a pawn and under our attack
-    Bitboard weakEnemies =  pos.pieces_of_color(Them)
+    Bitboard weakEnemies =  pos.pieces(Them)
                           & ~ei.attackedBy[Them][PAWN]
                           & ei.attackedBy[Us][0];
     if (!weakEnemies)
@@ -652,7 +651,7 @@ namespace {
     Score score = mobility = SCORE_ZERO;
 
     // Do not include in mobility squares protected by enemy pawns or occupied by our pieces
-    const Bitboard mobilityArea = ~(ei.attackedBy[Them][PAWN] | pos.pieces_of_color(Us));
+    const Bitboard mobilityArea = ~(ei.attackedBy[Them][PAWN] | pos.pieces(Us));
 
     score += evaluate_pieces<KNIGHT, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
     score += evaluate_pieces<BISHOP, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
@@ -706,7 +705,7 @@ namespace {
 
         // Analyse enemy's safe queen contact checks. First find undefended
         // squares around the king attacked by enemy queen...
-        b = undefended & ei.attackedBy[Them][QUEEN] & ~pos.pieces_of_color(Them);
+        b = undefended & ei.attackedBy[Them][QUEEN] & ~pos.pieces(Them);
         if (b)
         {
             // ...then remove squares not supported by another enemy piece
@@ -720,7 +719,7 @@ namespace {
 
         // Analyse enemy's safe rook contact checks. First find undefended
         // squares around the king attacked by enemy rooks...
-        b = undefended & ei.attackedBy[Them][ROOK] & ~pos.pieces_of_color(Them);
+        b = undefended & ei.attackedBy[Them][ROOK] & ~pos.pieces(Them);
 
         // Consider only squares where the enemy rook gives check
         b &= RookPseudoAttacks[ksq];
@@ -737,7 +736,7 @@ namespace {
         }
 
         // Analyse enemy's safe distance checks for sliders and knights
-        safe = ~(pos.pieces_of_color(Them) | ei.attackedBy[Us][0]);
+        safe = ~(pos.pieces(Them) | ei.attackedBy[Us][0]);
 
         b1 = pos.attacks_from<ROOK>(ksq) & safe;
         b2 = pos.attacks_from<BISHOP>(ksq) & safe;
@@ -813,9 +812,12 @@ namespace {
             Square blockSq = s + pawn_push(Us);
 
             // Adjust bonus based on kings proximity
-            ebonus -= Value(square_distance(pos.king_square(Us), blockSq) * 3 * rr);
-            ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * rr);
             ebonus += Value(square_distance(pos.king_square(Them), blockSq) * 6 * rr);
+            ebonus -= Value(square_distance(pos.king_square(Us), blockSq) * 3 * rr);
+
+            // If blockSq is not the queening square then consider also a second push
+            if (square_rank(blockSq) != (Us == WHITE ? RANK_8 : RANK_1))
+                ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * rr);
 
             // If the pawn is free to advance, increase bonus
             if (pos.square_is_empty(blockSq))
@@ -830,7 +832,7 @@ namespace {
                     && (squares_in_front_of(Them, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<ROOK>(s)))
                     unsafeSquares = squaresToQueen;
                 else
-                    unsafeSquares = squaresToQueen & (ei.attackedBy[Them][0] | pos.pieces_of_color(Them));
+                    unsafeSquares = squaresToQueen & (ei.attackedBy[Them][0] | pos.pieces(Them));
 
                 // If there aren't enemy attacks or pieces along the path to queen give
                 // huge bonus. Even bigger if we protect the pawn's path.
@@ -845,7 +847,7 @@ namespace {
 
                 // At last, add a small bonus when there are no *friendly* pieces
                 // in the pawn's path.
-                if (!(squaresToQueen & pos.pieces_of_color(Us)))
+                if (!(squaresToQueen & pos.pieces(Us)))
                     ebonus += Value(rr);
             }
         } // rr != 0
@@ -922,10 +924,10 @@ namespace {
             // Opponent king cannot block because path is defended and position
             // is not in check. So only friendly pieces can be blockers.
             assert(!pos.in_check());
-            assert(queeningPath & pos.occupied_squares() == queeningPath & pos.pieces_of_color(c));
+            assert((queeningPath & pos.occupied_squares()) == (queeningPath & pos.pieces(c)));
 
             // Add moves needed to free the path from friendly pieces and retest condition
-            movesToGo += count_1s<Max15>(queeningPath & pos.pieces_of_color(c));
+            movesToGo += count_1s<Max15>(queeningPath & pos.pieces(c));
 
             if (movesToGo >= oppMovesToGo && !pathDefended)
                 continue;
@@ -1076,8 +1078,8 @@ namespace {
   // apply_weight() applies an evaluation weight to a value trying to prevent overflow
 
   inline Score apply_weight(Score v, Score w) {
-      return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
-                        (int(eg_value(v)) * eg_value(w)) / 0x100);
+    return make_score((int(mg_value(v)) * mg_value(w)) / 0x100,
+                      (int(eg_value(v)) * eg_value(w)) / 0x100);
   }