X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=b33d2e976a8daef8584639ea827b6547d63e342d;hp=b63615a95ce439094835e8631128b699953e5188;hb=4b9e33854180ddba931a1f61368e2991a55a9651;hpb=ee5514b8fdc6583d134985edd2f875e197830030 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index b63615a9..b33d2e97 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -173,6 +173,7 @@ namespace { const Score RookOpenFile = make_score(43, 21); const Score RookSemiopenFile = make_score(19, 10); const Score BishopPawns = make_score( 8, 12); + const Score MinorBehindPawn = make_score(16, 0); const Score UndefendedMinor = make_score(25, 10); const Score TrappedRook = make_score(90, 0); @@ -238,18 +239,18 @@ namespace { Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score& mobility); template - Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]); + Score evaluate_king(const Position& pos, const EvalInfo& ei, Value margins[]); template - Score evaluate_threats(const Position& pos, EvalInfo& ei); + Score evaluate_threats(const Position& pos, const EvalInfo& ei); template - Score evaluate_passed_pawns(const Position& pos, EvalInfo& ei); + Score evaluate_passed_pawns(const Position& pos, const EvalInfo& ei); template - int evaluate_space(const Position& pos, EvalInfo& ei); + int evaluate_space(const Position& pos, const EvalInfo& ei); - Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei); + Score evaluate_unstoppable_pawns(const Position& pos, const EvalInfo& ei); Value interpolate(const Score& v, Phase ph, ScaleFactor sf); Score apply_weight(Score v, Score w); @@ -468,7 +469,7 @@ Value do_evaluate(const Position& pos, Value& margin) { if (bonus && (ei.attackedBy[Us][PAWN] & s)) { if ( !pos.pieces(Them, KNIGHT) - && !(same_color_squares(s) & pos.pieces(Them, BISHOP))) + && !(squares_of_color(s) & pos.pieces(Them, BISHOP))) bonus += bonus + bonus / 2; else bonus += bonus / 2; @@ -530,10 +531,17 @@ Value do_evaluate(const Position& pos, Value& margin) { if (Piece == BISHOP) score -= BishopPawns * ei.pi->pawns_on_same_color_squares(Us, s); - // Bishop and knight outposts squares - if ( (Piece == BISHOP || Piece == KNIGHT) - && !(pos.pieces(Them, PAWN) & pawn_attack_span(Us, s))) - score += evaluate_outposts(pos, ei, s); + if (Piece == BISHOP || Piece == KNIGHT) + { + // Bishop and knight outposts squares + if (!(pos.pieces(Them, PAWN) & pawn_attack_span(Us, s))) + score += evaluate_outposts(pos, ei, s); + + // Bishop or knight behind a pawn + if ( relative_rank(Us, s) < RANK_5 + && (pos.pieces(PAWN) & (s + pawn_push(Us)))) + score += MinorBehindPawn; + } if ( (Piece == ROOK || Piece == QUEEN) && relative_rank(Us, s) >= RANK_5) @@ -596,7 +604,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // and the type of attacked one. template - Score evaluate_threats(const Position& pos, EvalInfo& ei) { + Score evaluate_threats(const Position& pos, const EvalInfo& ei) { const Color Them = (Us == WHITE ? BLACK : WHITE); @@ -667,7 +675,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // evaluate_king<>() assigns bonuses and penalties to a king of a given color template - Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]) { + Score evaluate_king(const Position& pos, const EvalInfo& ei, Value margins[]) { const Color Them = (Us == WHITE ? BLACK : WHITE); @@ -767,7 +775,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // be very big, and so capturing a single attacking piece can therefore // result in a score change far bigger than the value of the captured piece. score -= KingDanger[Us == Search::RootColor][attackUnits]; - margins[Us] += mg_value(KingDanger[Us == Search::RootColor][attackUnits]) / 2; + margins[Us] += mg_value(KingDanger[Us == Search::RootColor][attackUnits]); } if (Trace) @@ -780,7 +788,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // evaluate_passed_pawns<>() evaluates the passed pawns of the given color template - Score evaluate_passed_pawns(const Position& pos, EvalInfo& ei) { + Score evaluate_passed_pawns(const Position& pos, const EvalInfo& ei) { const Color Them = (Us == WHITE ? BLACK : WHITE); @@ -818,7 +826,6 @@ Value do_evaluate(const Position& pos, Value& margin) { if (pos.is_empty(blockSq)) { squaresToQueen = forward_bb(Us, s); - defendedSquares = squaresToQueen & ei.attackedBy[Us][ALL_PIECES]; // If there is an enemy rook or queen attacking the pawn from behind, // add all X-ray attacks by the rook or queen. Otherwise consider only @@ -829,6 +836,12 @@ Value do_evaluate(const Position& pos, Value& margin) { else unsafeSquares = squaresToQueen & (ei.attackedBy[Them][ALL_PIECES] | pos.pieces(Them)); + if ( unlikely(forward_bb(Them, s) & pos.pieces(Us, ROOK, QUEEN)) + && (forward_bb(Them, s) & pos.pieces(Us, ROOK, QUEEN) & pos.attacks_from(s))) + defendedSquares = squaresToQueen; + else + defendedSquares = squaresToQueen & ei.attackedBy[Us][ALL_PIECES]; + // If there aren't enemy attacks huge bonus, a bit smaller if at // least block square is not attacked, otherwise smallest bonus. int k = !unsafeSquares ? 15 : !(unsafeSquares & blockSq) ? 9 : 3; @@ -882,7 +895,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // evaluate_unstoppable_pawns() evaluates the unstoppable passed pawns for both sides, this is quite // conservative and returns a winning score only when we are very sure that the pawn is winning. - Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei) { + Score evaluate_unstoppable_pawns(const Position& pos, const EvalInfo& ei) { Bitboard b, b2, blockers, supporters, queeningPath, candidates; Square s, blockSq, queeningSquare; @@ -1047,7 +1060,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // twice. Finally, the space bonus is scaled by a weight taken from the // material hash table. The aim is to improve play on game opening. template - int evaluate_space(const Position& pos, EvalInfo& ei) { + int evaluate_space(const Position& pos, const EvalInfo& ei) { const Color Them = (Us == WHITE ? BLACK : WHITE); @@ -1081,9 +1094,9 @@ Value do_evaluate(const Position& pos, Value& margin) { assert(eg_value(v) > -VALUE_INFINITE && eg_value(v) < VALUE_INFINITE); assert(ph >= PHASE_ENDGAME && ph <= PHASE_MIDGAME); - int ev = (eg_value(v) * int(sf)) / SCALE_FACTOR_NORMAL; - int result = (mg_value(v) * int(ph) + ev * int(128 - ph)) / 128; - return Value((result + GrainSize / 2) & ~(GrainSize - 1)); + int e = (eg_value(v) * int(sf)) / SCALE_FACTOR_NORMAL; + int r = (mg_value(v) * int(ph) + e * int(PHASE_MIDGAME - ph)) / PHASE_MIDGAME; + return Value((r / GrainSize) * GrainSize); // Sign independent } // apply_weight() weights score v by score w trying to prevent overflow @@ -1140,8 +1153,6 @@ Value do_evaluate(const Position& pos, Value& margin) { std::string Tracing::do_trace(const Position& pos) { - Search::RootColor = pos.side_to_move(); - stream.str(""); stream << std::showpoint << std::showpos << std::fixed << std::setprecision(2); std::memset(scores, 0, 2 * (TOTAL + 1) * sizeof(Score));