X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=1ff2dea7744c520daff7073c2bc315f0778648af;hp=63c0f1f80906076b84fdddf48a1f4df51801525b;hb=f011a5af116ed3331c7f6fb36a57d9e6de8a3ae6;hpb=d50b33cacd25483998a4bdc99038f4d1666c5d53 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 63c0f1f8..1ff2dea7 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -172,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 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 +201,12 @@ namespace { const int KingAttackWeights[] = { 0, 0, 2, 2, 3, 5 }; // Bonuses for enemy's safe checks - const int QueenContactCheck = 6; - const int RookContactCheck = 4; - const int QueenCheck = 3; - const int RookCheck = 2; - const int BishopCheck = 1; - const int KnightCheck = 1; + 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). @@ -232,7 +233,7 @@ namespace { void init_eval_info(const Position& pos, EvalInfo& ei); template - Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score& mobility); + Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score* mobility); template Score evaluate_king(const Position& pos, const EvalInfo& ei, Value margins[]); @@ -310,7 +311,7 @@ Value do_evaluate(const Position& pos, Value& margin) { EvalInfo ei; Value margins[COLOR_NB]; - Score score, mobilityWhite, mobilityBlack; + Score score, mobility[2] = { SCORE_ZERO, SCORE_ZERO }; Thread* th = pos.this_thread(); // margins[] store the uncertainty estimation of position's evaluation @@ -343,10 +344,10 @@ Value do_evaluate(const Position& pos, Value& margin) { init_eval_info(pos, ei); // Evaluate pieces and mobility - score += evaluate_pieces_of_color(pos, ei, mobilityWhite) - - evaluate_pieces_of_color(pos, ei, mobilityBlack); + score += evaluate_pieces_of_color(pos, ei, mobility) + - evaluate_pieces_of_color(pos, ei, mobility); - score += apply_weight(mobilityWhite - mobilityBlack, Weights[Mobility]); + score += apply_weight(mobility[WHITE] - mobility[BLACK], Weights[Mobility]); // Evaluate kings after all other pieces because we need complete attack // information when computing the king safety evaluation. @@ -443,7 +444,8 @@ Value do_evaluate(const Position& pos, Value& margin) { b &= ei.attackedBy[Us][PAWN]; ei.kingAttackersCount[Us] = b ? popcount(b) / 2 : 0; ei.kingAdjacentZoneAttacksCount[Us] = ei.kingAttackersWeight[Us] = 0; - } else + } + else ei.kingRing[Them] = ei.kingAttackersCount[Us] = 0; } @@ -470,14 +472,15 @@ Value do_evaluate(const Position& pos, Value& margin) { else bonus += bonus / 2; } + return make_score(bonus, bonus); } - // evaluate_pieces<>() assigns bonuses and penalties to the pieces of a given color + // evaluate_pieces() assigns bonuses and penalties to the pieces of a given color template - Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score& mobility, Bitboard mobilityArea) { + Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility, Bitboard mobilityArea) { Bitboard b; Square s; @@ -501,7 +504,7 @@ Value do_evaluate(const Position& pos, Value& margin) { { ei.kingAttackersCount[Us]++; ei.kingAttackersWeight[Us] += KingAttackWeights[Piece]; - Bitboard bb = (b & ei.attackedBy[Them][KING]); + Bitboard bb = b & ei.attackedBy[Them][KING]; if (bb) ei.kingAdjacentZoneAttacksCount[Us] += popcount(bb); } @@ -509,7 +512,7 @@ Value do_evaluate(const Position& pos, Value& margin) { int mob = Piece != QUEEN ? popcount(b & mobilityArea) : popcount(b & mobilityArea); - mobility += MobilityBonus[Piece][mob]; + mobility[Us] += MobilityBonus[Piece][mob]; // Decrease score if we are attacked by an enemy pawn. Remaining part // of threat evaluation must be done later when we have full attack info. @@ -527,6 +530,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 @@ -583,9 +590,9 @@ Value do_evaluate(const Position& pos, Value& margin) { const enum Piece P = make_piece(Us, PAWN); Square d = pawn_push(Us) + (file_of(s) == FILE_A ? DELTA_E : DELTA_W); if (pos.piece_on(s + d) == P) - score -= !pos.is_empty(s + d + pawn_push(Us)) ? TrappedBishopA1H1 * 4 - : pos.piece_on(s + d + d) == P ? TrappedBishopA1H1 * 2 - : TrappedBishopA1H1; + score -= !pos.empty(s + d + pawn_push(Us)) ? TrappedBishopA1H1 * 4 + : pos.piece_on(s + d + d) == P ? TrappedBishopA1H1 * 2 + : TrappedBishopA1H1; } } @@ -596,79 +603,34 @@ Value do_evaluate(const Position& pos, Value& margin) { } - // evaluate_threats<>() assigns bonuses according to the type of attacking piece - // and the type of attacked one. - - template - Score evaluate_threats(const Position& pos, const EvalInfo& ei) { - - const Color Them = (Us == WHITE ? BLACK : WHITE); - - Bitboard b, undefendedMinors, weakEnemies; - Score score = SCORE_ZERO; - - // Undefended minors get penalized even if not under attack - undefendedMinors = pos.pieces(Them, BISHOP, KNIGHT) - & ~ei.attackedBy[Them][ALL_PIECES]; - - if (undefendedMinors) - score += UndefendedMinor; - - // Enemy pieces not defended by a pawn and under our attack - weakEnemies = pos.pieces(Them) - & ~ei.attackedBy[Them][PAWN] - & ei.attackedBy[Us][ALL_PIECES]; - - // Add bonus according to type of attacked enemy piece and to the - // type of attacking piece, from knights to queens. Kings are not - // considered because are already handled in king evaluation. - if (weakEnemies) - for (PieceType pt1 = KNIGHT; pt1 < KING; ++pt1) - { - b = ei.attackedBy[Us][pt1] & weakEnemies; - if (b) - for (PieceType pt2 = PAWN; pt2 < KING; ++pt2) - if (b & pos.pieces(pt2)) - score += Threat[pt1][pt2]; - } - - if (Trace) - Tracing::scores[Us][THREAT] = score; - - return score; - } - - - // evaluate_pieces_of_color<>() assigns bonuses and penalties to all the + // evaluate_pieces_of_color() assigns bonuses and penalties to all the // pieces of a given color. template - Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score& mobility) { + Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score* mobility) { const Color Them = (Us == WHITE ? BLACK : WHITE); - Score score = mobility = SCORE_ZERO; - // Do not include in mobility squares protected by enemy pawns or occupied by our pieces const Bitboard mobilityArea = ~(ei.attackedBy[Them][PAWN] | pos.pieces(Us, PAWN, KING)); - score += evaluate_pieces(pos, ei, mobility, mobilityArea); - score += evaluate_pieces(pos, ei, mobility, mobilityArea); - score += evaluate_pieces(pos, ei, mobility, mobilityArea); - score += evaluate_pieces(pos, ei, mobility, mobilityArea); + Score score = evaluate_pieces(pos, ei, mobility, mobilityArea) + + evaluate_pieces(pos, ei, mobility, mobilityArea) + + evaluate_pieces(pos, ei, mobility, mobilityArea) + + evaluate_pieces(pos, ei, mobility, mobilityArea); - // Sum up all attacked squares - ei.attackedBy[Us][ALL_PIECES] = ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] - | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK] - | ei.attackedBy[Us][QUEEN] | ei.attackedBy[Us][KING]; + // Sum up all attacked squares (updated in evaluate_pieces) + ei.attackedBy[Us][ALL_PIECES] = ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] + | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK] + | ei.attackedBy[Us][QUEEN] | ei.attackedBy[Us][KING]; if (Trace) - Tracing::scores[Us][MOBILITY] = apply_weight(mobility, Weights[Mobility]); + Tracing::scores[Us][MOBILITY] = apply_weight(mobility[Us], Weights[Mobility]); return score; } - // evaluate_king<>() assigns bonuses and penalties to a king of a given color + // 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[]) { @@ -682,15 +644,15 @@ Value do_evaluate(const Position& pos, Value& margin) { // King shelter and enemy pawns storm Score score = ei.pi->king_safety(pos, ksq); - // King safety. This is quite complicated, and is almost certainly far - // from optimally tuned. + // Main king safety evaluation if ( ei.kingAttackersCount[Them] >= 2 && ei.kingAdjacentZoneAttacksCount[Them]) { // Find the attacked squares around the king which has no defenders // apart from the king itself - undefended = ei.attackedBy[Them][ALL_PIECES] & ei.attackedBy[Us][KING]; - undefended &= ~( ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] + undefended = ei.attackedBy[Them][ALL_PIECES] + & ei.attackedBy[Us][KING] + & ~( ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK] | ei.attackedBy[Us][QUEEN]); @@ -699,7 +661,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // number and types of the enemy's attacking pieces, the number of // attacked and undefended squares around our king, the square of the // king, and the quality of the pawn shelter. - attackUnits = std::min(25, (ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) / 2) + attackUnits = std::min(20, (ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) / 2) + 3 * (ei.kingAdjacentZoneAttacksCount[Them] + popcount(undefended)) + KingExposed[relative_square(Us, ksq)] - mg_value(score) / 32; @@ -781,7 +743,50 @@ Value do_evaluate(const Position& pos, Value& margin) { } - // evaluate_passed_pawns<>() evaluates the passed pawns of the given color + // evaluate_threats() assigns bonuses according to the type of attacking piece + // and the type of attacked one. + + template + Score evaluate_threats(const Position& pos, const EvalInfo& ei) { + + const Color Them = (Us == WHITE ? BLACK : WHITE); + + Bitboard b, undefendedMinors, weakEnemies; + Score score = SCORE_ZERO; + + // Undefended minors get penalized even if not under attack + undefendedMinors = pos.pieces(Them, BISHOP, KNIGHT) + & ~ei.attackedBy[Them][ALL_PIECES]; + + if (undefendedMinors) + score += UndefendedMinor; + + // Enemy pieces not defended by a pawn and under our attack + weakEnemies = pos.pieces(Them) + & ~ei.attackedBy[Them][PAWN] + & ei.attackedBy[Us][ALL_PIECES]; + + // Add bonus according to type of attacked enemy piece and to the + // type of attacking piece, from knights to queens. Kings are not + // considered because are already handled in king evaluation. + if (weakEnemies) + for (PieceType pt1 = KNIGHT; pt1 < KING; ++pt1) + { + b = ei.attackedBy[Us][pt1] & weakEnemies; + if (b) + for (PieceType pt2 = PAWN; pt2 < KING; ++pt2) + if (b & pos.pieces(pt2)) + score += Threat[pt1][pt2]; + } + + if (Trace) + Tracing::scores[Us][THREAT] = score; + + return score; + } + + + // evaluate_passed_pawns() evaluates the passed pawns of the given color template Score evaluate_passed_pawns(const Position& pos, const EvalInfo& ei) { @@ -797,7 +802,7 @@ Value do_evaluate(const Position& pos, Value& margin) { { Square s = pop_lsb(&b); - assert(pos.pawn_is_passed(Us, s)); + assert(pos.pawn_passed(Us, s)); int r = int(relative_rank(Us, s) - RANK_2); int rr = r * (r - 1); @@ -819,7 +824,7 @@ Value do_evaluate(const Position& pos, Value& margin) { 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)) + if (pos.empty(blockSq)) { squaresToQueen = forward_bb(Us, s); @@ -878,9 +883,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);