X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=279802387402906e969f1361eb2051a03a04efe7;hp=d87c51272862dac0cea0f79a7caf8dc2e4062f7b;hb=13d1f0ae4301b86c610a58332c3c19d9101704da;hpb=67f91bc5eaed821f35f09c9490a80200e1ab6951 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index d87c5127..27980238 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -83,6 +83,8 @@ namespace { // king is on g8 and there's a white knight on g5, this knight adds // 2 to kingAdjacentZoneAttacksCount[BLACK]. int kingAdjacentZoneAttacksCount[COLOR_NB]; + + Bitboard pinnedPieces[COLOR_NB]; }; // Evaluation grain size, must be a power of 2 @@ -172,6 +174,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 KnightPawns = make_score( 8, 4); const Score MinorBehindPawn = make_score(16, 0); const Score UndefendedMinor = make_score(25, 10); const Score TrappedRook = make_score(90, 0); @@ -200,12 +203,12 @@ namespace { const int KingAttackWeights[] = { 0, 0, 2, 2, 3, 5 }; // Bonuses for enemy's safe checks - const int QueenContactCheck = 12; - const int RookContactCheck = 8; - const int QueenCheck = 6; - const int RookCheck = 4; - const int BishopCheck = 1; - const int KnightCheck = 2; + const int QueenContactCheck = 24; + const int RookContactCheck = 16; + const int QueenCheck = 12; + const int RookCheck = 8; + const int BishopCheck = 2; + const int KnightCheck = 3; // KingExposed[Square] contains penalties based on the position of the // defending king, indexed by king's square (from white's point of view). @@ -226,7 +229,7 @@ namespace { // Function prototypes template - Value do_evaluate(const Position& pos, Value& margin); + Value do_evaluate(const Position& pos); template void init_eval_info(const Position& pos, EvalInfo& ei); @@ -235,7 +238,7 @@ namespace { Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score* mobility); template - Score evaluate_king(const Position& pos, const EvalInfo& ei, Value margins[]); + Score evaluate_king(const Position& pos, const EvalInfo& ei); template Score evaluate_threats(const Position& pos, const EvalInfo& ei); @@ -261,8 +264,8 @@ namespace Eval { /// values, an endgame score and a middle game score, and interpolates /// between them based on the remaining material. - Value evaluate(const Position& pos, Value& margin) { - return do_evaluate(pos, margin); + Value evaluate(const Position& pos) { + return do_evaluate(pos); } @@ -304,19 +307,14 @@ namespace Eval { namespace { template -Value do_evaluate(const Position& pos, Value& margin) { +Value do_evaluate(const Position& pos) { assert(!pos.checkers()); EvalInfo ei; - Value margins[COLOR_NB]; Score score, mobility[2] = { SCORE_ZERO, SCORE_ZERO }; Thread* th = pos.this_thread(); - // margins[] store the uncertainty estimation of position's evaluation - // that typically is used by the search for pruning decisions. - margins[WHITE] = margins[BLACK] = VALUE_ZERO; - // Initialize score by reading the incrementally updated scores included // in the position object (material + piece square tables) and adding // Tempo bonus. Score is computed from the point of view of white. @@ -329,10 +327,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // If we have a specialized evaluation function for the current material // configuration, call it and return. if (ei.mi->specialized_eval_exists()) - { - margin = VALUE_ZERO; return ei.mi->evaluate(pos); - } // Probe the pawn hash table ei.pi = Pawns::probe(pos, th->pawnsTable); @@ -350,8 +345,8 @@ Value do_evaluate(const Position& pos, Value& margin) { // Evaluate kings after all other pieces because we need complete attack // information when computing the king safety evaluation. - score += evaluate_king(pos, ei, margins) - - evaluate_king(pos, ei, margins); + score += evaluate_king(pos, ei) + - evaluate_king(pos, ei); // Evaluate tactical threats, we need full attack information including king score += evaluate_threats(pos, ei) @@ -398,7 +393,6 @@ Value do_evaluate(const Position& pos, Value& margin) { sf = ScaleFactor(50); } - margin = margins[pos.side_to_move()]; Value v = interpolate(score, ei.mi->game_phase(), sf); // In case of tracing add all single evaluation contributions for both white and black @@ -411,9 +405,7 @@ Value do_evaluate(const Position& pos, Value& margin) { 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]) - << ", Black: " << to_cp(margins[BLACK]) - << "\nScaling: " << std::noshowpos + Tracing::stream << "\nScaling: " << std::noshowpos << std::setw(6) << 100.0 * ei.mi->game_phase() / 128.0 << "% MG, " << std::setw(6) << 100.0 * (1.0 - ei.mi->game_phase() / 128.0) << "% * " << std::setw(6) << (100.0 * sf) / SCALE_FACTOR_NORMAL << "% EG.\n" @@ -433,6 +425,8 @@ Value do_evaluate(const Position& pos, Value& margin) { const Color Them = (Us == WHITE ? BLACK : WHITE); const Square Down = (Us == WHITE ? DELTA_S : DELTA_N); + ei.pinnedPieces[Us] = pos.pinned_pieces(Us); + Bitboard b = ei.attackedBy[Them][KING] = pos.attacks_from(pos.king_square(Them)); ei.attackedBy[Us][PAWN] = ei.pi->pawn_attacks(Us); @@ -497,6 +491,9 @@ Value do_evaluate(const Position& pos, Value& margin) { : Piece == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(Us, ROOK, QUEEN)) : pos.attacks_from(s); + if (ei.pinnedPieces[Us] & s) + b &= PseudoAttacks[QUEEN][pos.king_square(Us)]; + ei.attackedBy[Us][Piece] |= b; if (b & ei.kingRing[Them]) @@ -508,7 +505,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[Us] += MobilityBonus[Piece][mob]; // Decrease score if we are attacked by an enemy pawn. Remaining part @@ -527,6 +526,10 @@ Value do_evaluate(const Position& pos, Value& margin) { if (Piece == BISHOP) score -= BishopPawns * ei.pi->pawns_on_same_color_squares(Us, s); + // Penalty for knight when there are few enemy pawns + if (Piece == KNIGHT) + score -= KnightPawns * std::max(5 - pos.count(Them), 0); + if (Piece == BISHOP || Piece == KNIGHT) { // Bishop and knight outposts squares @@ -626,7 +629,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, const EvalInfo& ei, Value margins[]) { + Score evaluate_king(const Position& pos, const EvalInfo& ei) { const Color Them = (Us == WHITE ? BLACK : WHITE); @@ -721,12 +724,8 @@ Value do_evaluate(const Position& pos, Value& margin) { attackUnits = std::min(99, std::max(0, attackUnits)); // Finally, extract the king danger score from the KingDanger[] - // array and subtract the score from evaluation. Set also margins[] - // value that will be used for pruning because this value can sometimes - // 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. + // array and subtract the score from evaluation. score -= KingDanger[Us == Search::RootColor][attackUnits]; - margins[Us] += mg_value(KingDanger[Us == Search::RootColor][attackUnits]); } if (Trace) @@ -876,9 +875,7 @@ Value do_evaluate(const Position& pos, Value& margin) { ebonus -= ebonus / 4; } - // Increase the bonus if we have more non-pawn pieces - if (pos.count( Us) - pos.count( Us) > - pos.count(Them) - pos.count(Them)) + if (pos.count(Us) < pos.count(Them)) ebonus += ebonus / 4; score += make_score(mbonus, ebonus); @@ -1012,8 +1009,7 @@ Value do_evaluate(const Position& pos, Value& margin) { stream << std::showpoint << std::showpos << std::fixed << std::setprecision(2); std::memset(scores, 0, 2 * (TOTAL + 1) * sizeof(Score)); - Value margin; - do_evaluate(pos, margin); + do_evaluate(pos); std::string totals = stream.str(); stream.str("");