X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=b33d2e976a8daef8584639ea827b6547d63e342d;hp=c5af2f89524e5f9c04b89bb5c1780d8caa105911;hb=4b9e33854180ddba931a1f61368e2991a55a9651;hpb=6fbe027da05d6de0b7f03e8696bbde2e33baad98 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index c5af2f89..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); @@ -372,7 +373,7 @@ Value do_evaluate(const Position& pos, Value& margin) { if (ei.mi->space_weight()) { int s = evaluate_space(pos, ei) - evaluate_space(pos, ei); - score += apply_weight(make_score(s * ei.mi->space_weight(), 0), Weights[Space]); + score += apply_weight(s * ei.mi->space_weight(), Weights[Space]); } // Scale winning side if position is more drawish that what it appears @@ -410,8 +411,8 @@ Value do_evaluate(const Position& pos, Value& margin) { Tracing::add(IMBALANCE, ei.mi->material_value()); Tracing::add(PAWN, ei.pi->pawns_value()); Tracing::add(UNSTOPPABLE, evaluate_unstoppable_pawns(pos, ei)); - Score w = make_score(ei.mi->space_weight() * evaluate_space(pos, ei), 0); - Score b = make_score(ei.mi->space_weight() * evaluate_space(pos, ei), 0); + Score w = ei.mi->space_weight() * evaluate_space(pos, ei); + Score b = ei.mi->space_weight() * evaluate_space(pos, ei); Tracing::add(SPACE, apply_weight(w, Weights[Space]), apply_weight(b, Weights[Space])); Tracing::add(TOTAL, score); Tracing::stream << "\nUncertainty margin: White: " << to_cp(margins[WHITE]) @@ -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; @@ -509,7 +510,9 @@ Value do_evaluate(const Position& pos, Value& margin) { ei.kingAdjacentZoneAttacksCount[Us] += popcount(bb); } - int mob = popcount(b & mobilityArea); + int mob = Piece != QUEEN ? popcount(b & mobilityArea) + : popcount(b & mobilityArea); + mobility += MobilityBonus[Piece][mob]; // Decrease score if we are attacked by an enemy pawn. Remaining part @@ -528,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) @@ -554,7 +564,7 @@ Value do_evaluate(const Position& pos, Value& margin) { if (ei.pi->semiopen(Us, file_of(s))) score += ei.pi->semiopen(Them, file_of(s)) ? RookOpenFile : RookSemiopenFile; - if (mob > 6 || ei.pi->semiopen(Us, file_of(s))) + if (mob > 3 || ei.pi->semiopen(Us, file_of(s))) continue; Square ksq = pos.king_square(Us); @@ -594,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); @@ -665,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); @@ -778,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); @@ -816,17 +826,22 @@ 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 // the squares in the pawn's path attacked or occupied by the enemy. - if ( (forward_bb(Them, s) & pos.pieces(Them, ROOK, QUEEN)) // Unlikely + if ( unlikely(forward_bb(Them, s) & pos.pieces(Them, ROOK, QUEEN)) && (forward_bb(Them, s) & pos.pieces(Them, ROOK, QUEEN) & pos.attacks_from(s))) unsafeSquares = squaresToQueen; 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; @@ -880,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; @@ -1045,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); @@ -1079,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 @@ -1138,11 +1153,9 @@ 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); - memset(scores, 0, 2 * (TOTAL + 1) * sizeof(Score)); + std::memset(scores, 0, 2 * (TOTAL + 1) * sizeof(Score)); Value margin; do_evaluate(pos, margin);