X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=c7fec9131e11ceeef0b1499c92b2ea1c012c0d83;hp=c5af2f89524e5f9c04b89bb5c1780d8caa105911;hb=03cd049c6858f5d1c4b7e50f08d7ddc45e0a029e;hpb=6fbe027da05d6de0b7f03e8696bbde2e33baad98 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index c5af2f89..c7fec913 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -114,16 +114,15 @@ namespace { S( 37, 28), S( 42, 31), S(44, 33) }, { S(-22,-27), S( -8,-13), S( 6, 1), S(20, 15), S(34, 29), S(48, 43), // Bishops S( 60, 55), S( 68, 63), S(74, 68), S(77, 72), S(80, 75), S(82, 77), - S( 84, 79), S( 86, 81), S(87, 82), S(87, 82) }, + S( 84, 79), S( 86, 81) }, { S(-17,-33), S(-11,-16), S(-5, 0), S( 1, 16), S( 7, 32), S(13, 48), // Rooks S( 18, 64), S( 22, 80), S(26, 96), S(29,109), S(31,115), S(33,119), - S( 35,122), S( 36,123), S(37,124), S(38,124) }, + S( 35,122), S( 36,123), S(37,124) }, { S(-12,-20), S( -8,-13), S(-5, -7), S(-2, -1), S( 1, 5), S( 4, 11), // Queens S( 7, 17), S( 10, 23), S(13, 29), S(16, 34), S(18, 38), S(20, 40), S( 22, 41), S( 23, 41), S(24, 41), S(25, 41), S(25, 41), S(25, 41), S( 25, 41), S( 25, 41), S(25, 41), S(25, 41), S(25, 41), S(25, 41), - S( 25, 41), S( 25, 41), S(25, 41), S(25, 41), S(25, 41), S(25, 41), - S( 25, 41), S( 25, 41) } + S( 25, 41), S( 25, 41), S(25, 41), S(25, 41) } }; // Outpost[PieceType][Square] contains bonuses of knights and bishops, indexed @@ -173,6 +172,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 +238,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 +372,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 +410,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 +468,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 +509,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 +530,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 +563,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 +603,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 +674,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 +787,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); @@ -809,24 +818,29 @@ Value do_evaluate(const Position& pos, Value& margin) { ebonus -= Value(square_distance(pos.king_square(Us), blockSq) * 2 * rr); // If blockSq is not the queening square then consider also a second push - if (rank_of(blockSq) != (Us == WHITE ? RANK_8 : RANK_1)) + if (relative_rank(Us, blockSq) != RANK_8) ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * rr); // If the pawn is free to advance, increase bonus 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 +894,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 +1059,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 +1093,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 +1152,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);