X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=406d07459df577af3c617b40b91d2257a1774d32;hp=897fc778a467ded318fbbba61f0dc047af32845a;hb=5a42427cb882f8adcfe65d41f4fabac5d2ac4a5b;hpb=55758344d3ccf49353bcd8f3a06a4553ff1b753a diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 897fc778..406d0745 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -107,10 +107,10 @@ namespace { // Evaluation weights, indexed by the corresponding evaluation term - enum { Mobility, PawnStructure, PassedPawns, Space, KingSafety }; + enum { Mobility, PawnStructure, PassedPawns, Space, KingSafety, Threats }; const struct Weight { int mg, eg; } Weights[] = { - {289, 344}, {233, 201}, {221, 273}, {46, 0}, {322, 0} + {289, 344}, {233, 201}, {221, 273}, {46, 0}, {322, 0}, {350, 256} }; Score operator*(Score s, const Weight& w) { @@ -141,6 +141,11 @@ namespace { S(112,125), S(113,127), S(117,137), S(122,143) } }; + // Mask of allowed outpost squares indexed by color + const Bitboard OutpostMask[COLOR_NB] = { + Rank4BB | Rank5BB | Rank6BB, Rank5BB | Rank4BB | Rank3BB + }; + // Outpost[knight/bishop][supported by pawn] contains bonuses for knights and // bishops outposts, bigger if outpost piece is supported by a pawn. const Score Outpost[][2] = { @@ -148,6 +153,13 @@ namespace { { S(18, 5), S(27, 8) } // Bishops }; + // ReachableOutpost[knight/bishop][supported by pawn] contains bonuses for knights and + // bishops which can reach a outpost square in one move, bigger if outpost square is supported by a pawn. + const Score ReachableOutpost[][2] = { + { S(21, 5), S(31, 8) }, // Knights + { S( 8, 2), S(13, 4) } // Bishops + }; + // Threat[minor/rook][attacked PieceType] contains // bonuses according to which piece type attacks which one. // Attacks on lesser pieces which are pawn defended are not considered. @@ -171,8 +183,8 @@ namespace { // PassedFile[File] contains a bonus according to the file of a passed pawn. const Score PassedFile[] = { - S( 12, 10), S( 3, 10), S( 1, -8), S(-27, -12), - S(-27, -12), S( 1, -8), S( 3, 10), S( 12, 10) + S( 12, 10), S( 3, 10), S( 1, -8), S(-27, -12), + S(-27, -12), S( 1, -8), S( 3, 10), S( 12, 10) }; const Score ThreatenedByHangingPawn = S(40, 60); @@ -257,7 +269,7 @@ namespace { template Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility, const Bitboard* mobilityArea) { - Bitboard b; + Bitboard b, bb; Square s; Score score = SCORE_ZERO; @@ -283,7 +295,7 @@ namespace { { ei.kingAttackersCount[Us]++; ei.kingAttackersWeight[Us] += KingAttackWeights[Pt]; - Bitboard bb = b & ei.attackedBy[Them][KING]; + bb = b & ei.attackedBy[Them][KING]; if (bb) ei.kingAdjacentZoneAttacksCount[Us] += popcount(bb); } @@ -299,11 +311,16 @@ namespace { if (Pt == BISHOP || Pt == KNIGHT) { - // Bonus for outpost square - if ( relative_rank(Us, s) >= RANK_4 - && relative_rank(Us, s) <= RANK_6 - && !(pos.pieces(Them, PAWN) & pawn_attack_span(Us, s))) + // Bonus for outpost squares + bb = OutpostMask[Us] & ~ei.pi->pawn_attacks_span(Them); + if (bb & s) score += Outpost[Pt == BISHOP][!!(ei.attackedBy[Us][PAWN] & s)]; + else + { + bb &= b & ~pos.pieces(Us); + if (bb) + score += ReachableOutpost[Pt == BISHOP][!!(ei.attackedBy[Us][PAWN] & bb)]; + } // Bonus when behind a pawn if ( relative_rank(Us, s) < RANK_5 @@ -549,9 +566,9 @@ namespace { score += popcount(b) * PawnAttackThreat; if (DoTrace) - Trace::add(THREAT, Us, score); + Trace::add(THREAT, Us, score * Weights[Threats]); - return score; + return score * Weights[Threats]; } @@ -677,20 +694,18 @@ namespace { // 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) { + Score evaluate_initiative(const Position& pos, int asymmetry, Value eg) { - int king_separation = distance(pos.square(WHITE), pos.square(BLACK)); - int pawns = pos.count(WHITE) + pos.count(BLACK); - int asymmetry = ei.pi->pawn_asymmetry(); + int kingDistance = distance(pos.square(WHITE), pos.square(BLACK)); + int pawns = pos.count(WHITE) + pos.count(BLACK); // Compute the initiative bonus for the attacking side - int attacker_bonus = 8 * (pawns + asymmetry + king_separation) - 120; + int initiative = 8 * (pawns + asymmetry + kingDistance - 15); - // 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)); + // Now apply the bonus: note that we find the attacking side by extracting + // the sign of the endgame value, and that we carefully cap the bonus so + // that the endgame score will never be divided by more than two. + int value = ((eg > 0) - (eg < 0)) * std::max(initiative, -abs(eg / 2)); return make_score(0, value); } @@ -777,8 +792,8 @@ Value Eval::evaluate(const Position& pos) { 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); + // Evaluate position potential for the winning side + score += evaluate_initiative(pos, ei.pi->pawn_asymmetry(), eg_value(score)); // Scale winning side if position is more drawish than it appears Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK;