X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fevaluate.cpp;h=bbca9964f4337d9506c23d0d49353af9f0e2e9d3;hb=7ea5659c5fe0325f1b6ee5fec06ecd0f066e81c3;hp=8fd405d0036fe9e41c7632b2fa108bdf77a8db25;hpb=436c3037310ad997f85a5da0685b6bc91699163b;p=stockfish diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 8fd405d0..bbca9964 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -220,9 +220,8 @@ namespace { // Penalties for enemy's safe checks const int QueenContactCheck = 89; - const int RookContactCheck = 71; const int QueenCheck = 50; - const int RookCheck = 37; + const int RookCheck = 45; const int BishopCheck = 6; const int KnightCheck = 14; @@ -421,23 +420,6 @@ namespace { attackUnits += QueenContactCheck * popcount(b); } - // Analyse the enemy's safe rook contact checks. Firstly, find the - // undefended squares around the king reachable by the enemy rooks... - b = undefended & ei.attackedBy[Them][ROOK] & ~pos.pieces(Them); - - // Consider only squares where the enemy's rook gives check - b &= PseudoAttacks[ROOK][ksq]; - - if (b) - { - // ...and then remove squares not supported by another enemy piece - b &= ( ei.attackedBy[Them][PAWN] | ei.attackedBy[Them][KNIGHT] - | ei.attackedBy[Them][BISHOP]); - - if (b) - attackUnits += RookContactCheck * popcount(b); - } - // Analyse the enemy's safe distance checks for sliders and knights safe = ~(ei.attackedBy[Us][ALL_PIECES] | pos.pieces(Them)); @@ -704,6 +686,27 @@ namespace { return make_score(bonus * weight * weight, 0); } + + // evaluate_initiative() computes the initiative correction value for the position, i.e. + // second order bonus/malus based on the known attacking/defending status of the players. + Score evaluate_initiative(const Position& pos, const EvalInfo& ei, const Score positional_score) { + + int pawns = pos.count(WHITE) + pos.count(BLACK); + int king_separation = distance(pos.square(WHITE), pos.square(BLACK)); + int asymmetry = ei.pi->pawn_asymmetry(); + + // Compute the initiative bonus for the attacking side + int attacker_bonus = 8 * (pawns + asymmetry + king_separation) - 120; + + // Now apply the bonus: note that we find the attacking side by extracting the sign + // of the endgame value of "positional_score", and that we carefully cap the bonus so + // that the endgame score with the correction will never be divided by more than two. + int eg = eg_value(positional_score); + int value = ((eg > 0) - (eg < 0)) * std::max( attacker_bonus , -abs( eg / 2 ) ); + + return make_score( 0 , value ) ; + } + } // namespace @@ -785,6 +788,9 @@ Value Eval::evaluate(const Position& pos) { // Evaluate space for both sides, only during opening if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 12222) score += (evaluate_space(pos, ei) - evaluate_space(pos, ei)) * Weights[Space]; + + // Evaluate initiative + score += evaluate_initiative(pos, ei, score); // Scale winning side if position is more drawish than it appears Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK; @@ -816,11 +822,6 @@ Value Eval::evaluate(const Position& pos) { sf = ei.pi->pawn_span(strongSide) ? ScaleFactor(51) : ScaleFactor(37); } - // Scale endgame by number of pawns - int p = pos.count(WHITE) + pos.count(BLACK); - int v_eg = 1 + abs(int(eg_value(score))); - sf = ScaleFactor(std::max(sf / 2, sf - 8 * SCALE_FACTOR_NORMAL * (12 - p) / v_eg)); - // Interpolate between a middlegame and a (scaled by 'sf') endgame score Value v = mg_value(score) * int(me->game_phase()) + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;