X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=5a28b286ae0a354c1f01eb6c445fb83fc85eaa13;hp=84b9d1154bc46c439d2e5aefa1b3c7c00a1d2370;hb=a9b8e8b9318130621acf21f5a2b3a705b63907d3;hpb=e10276f45d33c39085bb2c1435155d9cf9a57681 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 84b9d115..5a28b286 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -147,7 +147,7 @@ namespace { // ThreatenedByPawn[PieceType] contains a penalty according to which piece // type is attacked by an enemy pawn. const Score ThreatenedByPawn[] = { - S(0, 0), S(0, 0), S(56, 70), S(56, 70), S(76, 99), S(86, 118) + S(0, 0), S(0, 0), S(80, 119), S(80, 119), S(117, 199), S(127, 218) }; // Hanging contains a bonus for each enemy hanging piece @@ -160,7 +160,7 @@ namespace { const Score RookSemiopenFile = make_score(19, 10); const Score BishopPawns = make_score( 8, 12); const Score MinorBehindPawn = make_score(16, 0); - const Score TrappedRook = make_score(90, 0); + const Score TrappedRook = make_score(92, 0); const Score Unstoppable = make_score( 0, 20); // Penalty for a bishop on a1/h1 (a8/h8 for black) which is trapped by @@ -197,6 +197,7 @@ namespace { // scores, indexed by a calculated integer number. Score KingDanger[128]; + const int ScalePawnSpan[2] = { 38, 56 }; // apply_weight() weighs score 'v' by weight 'w' trying to prevent overflow Score apply_weight(Score v, const Weight& w) { @@ -349,7 +350,7 @@ namespace { if ( ((file_of(ksq) < FILE_E) == (file_of(s) < file_of(ksq))) && (rank_of(ksq) == rank_of(s) || relative_rank(Us, ksq) == RANK_1) && !ei.pi->semiopen_side(Us, file_of(ksq), file_of(s) < file_of(ksq))) - score -= (TrappedRook - make_score(mob * 8, 0)) * (1 + !pos.can_castle(Us)); + score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.can_castle(Us)); } // An important Chess960 pattern: A cornered bishop blocked by a friendly @@ -495,9 +496,17 @@ namespace { const Color Them = (Us == WHITE ? BLACK : WHITE); - Bitboard b, weakEnemies; + Bitboard b, weakEnemies, protectedEnemies; Score score = SCORE_ZERO; + // Protected enemies + protectedEnemies = (pos.pieces(Them) ^ pos.pieces(Them,PAWN)) + & ei.attackedBy[Them][PAWN] + & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]); + + if(protectedEnemies) + score += Threat[0][type_of(pos.piece_on(lsb(protectedEnemies)))]; + // Enemies not defended by a pawn and under our attack weakEnemies = pos.pieces(Them) & ~ei.attackedBy[Them][PAWN] @@ -506,7 +515,7 @@ namespace { // Add a bonus according if the attacking pieces are minor or major if (weakEnemies) { - b = weakEnemies & (ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]); + b = weakEnemies & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]); if (b) score += Threat[0][type_of(pos.piece_on(lsb(b)))]; @@ -596,6 +605,8 @@ namespace { mbonus += k * rr, ebonus += k * rr; } + else if(pos.pieces(Us) & blockSq) + mbonus += rr * 3 + r * 2 + 3, ebonus += rr + r * 2; } // rr != 0 if (pos.count(Us) < pos.count(Them)) @@ -613,17 +624,14 @@ namespace { // evaluate_unstoppable_pawns() scores the most advanced among the passed and - // candidate pawns. In case opponent has no pieces but pawns, this is somewhat - // related to the possibility that pawns are unstoppable. + // candidate pawns. In case both players have no pieces but pawns, this is + // somewhat related to the possibility that pawns are unstoppable. - Score evaluate_unstoppable_pawns(const Position& pos, Color us, const EvalInfo& ei) { + Score evaluate_unstoppable_pawns(Color us, const EvalInfo& ei) { Bitboard b = ei.pi->passed_pawns(us) | ei.pi->candidate_pawns(us); - if (!b || pos.non_pawn_material(~us)) - return SCORE_ZERO; - - return Unstoppable * int(relative_rank(us, frontmost_sq(us, b))); + return b ? Unstoppable * int(relative_rank(us, frontmost_sq(us, b))) : SCORE_ZERO; } @@ -716,10 +724,10 @@ namespace { score += evaluate_passed_pawns(pos, ei) - evaluate_passed_pawns(pos, ei); - // If one side has only a king, score for potential unstoppable pawns - if (!pos.non_pawn_material(WHITE) || !pos.non_pawn_material(BLACK)) - score += evaluate_unstoppable_pawns(pos, WHITE, ei) - - evaluate_unstoppable_pawns(pos, BLACK, ei); + // If both sides have only pawns, score for potential unstoppable pawns + if (!pos.non_pawn_material(WHITE) && !pos.non_pawn_material(BLACK)) + score += evaluate_unstoppable_pawns(WHITE, ei) + - evaluate_unstoppable_pawns(BLACK, ei); // Evaluate space for both sides, only in middlegame if (ei.mi->space_weight()) @@ -729,29 +737,35 @@ namespace { } // Scale winning side if position is more drawish than it appears - ScaleFactor sf = eg_value(score) > VALUE_DRAW ? ei.mi->scale_factor(pos, WHITE) - : ei.mi->scale_factor(pos, BLACK); + Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK; + ScaleFactor sf = ei.mi->scale_factor(pos, strongSide); - // If we don't already have an unusual scale factor, check for opposite - // colored bishop endgames, and use a lower scale for those. + // If we don't already have an unusual scale factor, check for certain + // types of endgames, and use a lower scale for those. if ( ei.mi->game_phase() < PHASE_MIDGAME - && pos.opposite_bishops() && (sf == SCALE_FACTOR_NORMAL || sf == SCALE_FACTOR_ONEPAWN)) { - // Ignoring any pawns, do both sides only have a single bishop and no - // other pieces? - if ( pos.non_pawn_material(WHITE) == BishopValueMg - && pos.non_pawn_material(BLACK) == BishopValueMg) - { - // Check for KBP vs KB with only a single pawn that is almost - // certainly a draw or at least two pawns. - bool one_pawn = (pos.count(WHITE) + pos.count(BLACK) == 1); - sf = one_pawn ? ScaleFactor(8) : ScaleFactor(32); + if (pos.opposite_bishops()) { + // Ignoring any pawns, do both sides only have a single bishop and no + // other pieces? + if ( pos.non_pawn_material(WHITE) == BishopValueMg + && pos.non_pawn_material(BLACK) == BishopValueMg) + { + // Check for KBP vs KB with only a single pawn that is almost + // certainly a draw or at least two pawns. + bool one_pawn = (pos.count(WHITE) + pos.count(BLACK) == 1); + sf = one_pawn ? ScaleFactor(8) : ScaleFactor(32); + } + else + // Endgame with opposite-colored bishops, but also other pieces. Still + // a bit drawish, but not as drawish as with only the two bishops. + sf = ScaleFactor(50 * sf / SCALE_FACTOR_NORMAL); + } else if ( abs(eg_value(score)) <= BishopValueEg + && ei.pi->pawn_span(strongSide) <= 1 + && !pos.pawn_passed(~strongSide, pos.king_square(~strongSide))) { + // Endings where weaker side can be place his king in front of the opponent's pawns are drawish. + sf = ScaleFactor(ScalePawnSpan[ei.pi->pawn_span(strongSide)]); } - else - // Endgame with opposite-colored bishops, but also other pieces. Still - // a bit drawish, but not as drawish as with only the two bishops. - sf = ScaleFactor(50 * sf / SCALE_FACTOR_NORMAL); } // Interpolate between a middlegame and a (scaled by 'sf') endgame score