X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=9521cd100282487f44ba3926f01afde124797bc6;hp=edebb2695656ae6309549bda4c69f72a5e04a8f4;hb=7e4c3256aab178f303578b4c4a31c59d43421640;hpb=66a3c2968b8552efce8c7e670d7ceabb28f9c1eb diff --git a/src/evaluate.cpp b/src/evaluate.cpp index edebb269..9521cd10 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -140,6 +140,7 @@ namespace { constexpr Score PawnlessFlank = S( 17, 95); constexpr Score RestrictedPiece = S( 7, 7); constexpr Score RookOnPawn = S( 10, 32); + constexpr Score RookOnQueenFile = S( 11, 4); constexpr Score SliderOnQueen = S( 59, 18); constexpr Score ThreatByKing = S( 24, 89); constexpr Score ThreatByPawnPush = S( 48, 39); @@ -168,7 +169,7 @@ namespace { template Score passed() const; template Score space() const; ScaleFactor scale_factor(Value eg) const; - Score initiative(Value eg) const; + Score initiative(Score score) const; const Position& pos; Material::Entry* me; @@ -346,9 +347,13 @@ namespace { if (relative_rank(Us, s) >= RANK_5) score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]); + // Bonus for rook on the same file as a queen + if (file_bb(s) & pos.pieces(QUEEN)) + score += RookOnQueenFile; + // Bonus for rook on an open or semi-open file if (pos.is_on_semiopen_file(Us, s)) - score += RookOnFile[bool(pos.is_on_semiopen_file(Them, s))]; + score += RookOnFile[pos.is_on_semiopen_file(Them, s)]; // Penalty when trapped by the king, even more if the king cannot castle else if (mob <= 3) @@ -505,9 +510,6 @@ namespace { // Enemies not strongly protected and under our attack weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES]; - // Safe or protected squares - safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES]; - // Bonus according to the kind of attacking pieces if (defended | weak) { @@ -544,6 +546,14 @@ namespace { score += RestrictedPiece * popcount(b); + // Protected or unattacked squares + safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES]; + + // Bonus for attacking enemy pieces with our relatively safe pawns + b = pos.pieces(Us, PAWN) & safe; + b = pawn_attacks_bb(b) & nonPawnEnemies; + score += ThreatBySafePawn * popcount(b); + // Find squares where our pawns can push on the next move b = shift(pos.pieces(Us, PAWN)) & ~pos.pieces(); b |= shift(b & TRank3BB) & ~pos.pieces(); @@ -555,12 +565,6 @@ namespace { b = pawn_attacks_bb(b) & nonPawnEnemies; score += ThreatByPawnPush * popcount(b); - // Our safe or protected pawns - b = pos.pieces(Us, PAWN) & safe; - - b = pawn_attacks_bb(b) & nonPawnEnemies; - score += ThreatBySafePawn * popcount(b); - // Bonus for threats on the next moves against enemy queen if (pos.count(Them) == 1) { @@ -713,7 +717,10 @@ namespace { // known attacking/defending status of the players. template - Score Evaluation::initiative(Value eg) const { + Score Evaluation::initiative(Score score) const { + + Value mg = mg_value(score); + Value eg = eg_value(score); int outflanking = distance(pos.square(WHITE), pos.square(BLACK)) - distance(pos.square(WHITE), pos.square(BLACK)); @@ -721,23 +728,29 @@ namespace { bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide) && (pos.pieces(PAWN) & KingSide); + bool almostUnwinnable = !pe->passed_count() + && outflanking < 0 + && !pawnsOnBothFlanks; + // Compute the initiative bonus for the attacking side int complexity = 9 * pe->passed_count() + 11 * pos.count() + 9 * outflanking + 18 * pawnsOnBothFlanks + 49 * !pos.non_pawn_material() + - 36 * almostUnwinnable -103 ; - // Now apply the bonus: note that we find the attacking side by extracting - // the sign of the endgame value, and that we carefully cap the bonus so - // that the endgame score will never change sign after the bonus. + // Now apply the bonus: note that we find the attacking side by extracting the + // sign of the midgame or endgame values, and that we carefully cap the bonus + // so that the midgame and endgame scores do not change sign after the bonus. + int u = ((mg > 0) - (mg < 0)) * std::max(std::min(complexity + 50, 0), -abs(mg)); int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg)); if (T) - Trace::add(INITIATIVE, make_score(0, v)); + Trace::add(INITIATIVE, make_score(u, v)); - return make_score(0, v); + return make_score(u, v); } @@ -756,8 +769,9 @@ namespace { && pos.non_pawn_material() == 2 * BishopValueMg) sf = 16 + 4 * pe->passed_count(); else - sf = std::min(40 + (pos.opposite_bishops() ? 2 : 7) * pos.count(strongSide), sf); + sf = std::min(sf, 36 + (pos.opposite_bishops() ? 2 : 7) * pos.count(strongSide)); + sf = std::max(0, sf - (pos.rule50_count() - 12) / 4 ); } return ScaleFactor(sf); @@ -813,7 +827,7 @@ namespace { + passed< WHITE>() - passed< BLACK>() + space< WHITE>() - space< BLACK>(); - score += initiative(eg_value(score)); + score += initiative(score); // Interpolate between a middlegame and a (scaled by 'sf') endgame score ScaleFactor sf = scale_factor(eg_value(score));