X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=1505bf67facd53bcd028eac73d795b25d49ee8af;hp=48c6e8ea1d7befaee0235485fcd07a4a28b5c412;hb=66af80972a6ae085f6348d38ca5e4eb08734437d;hpb=ed26d71354c3ab1a1419975430258b6e961787a7 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 48c6e8ea..1505bf67 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -28,8 +28,7 @@ #include "evaluate.h" #include "material.h" #include "pawns.h" - -std::atomic Eval::Contempt; +#include "thread.h" namespace Trace { @@ -172,6 +171,7 @@ namespace { constexpr Score KnightOnQueen = S( 21, 11); constexpr Score LongDiagonalBishop = S( 22, 0); constexpr Score MinorBehindPawn = S( 16, 0); + constexpr Score Overload = S( 10, 5); constexpr Score PawnlessFlank = S( 20, 80); constexpr Score RookOnPawn = S( 8, 24); constexpr Score SliderOnQueen = S( 42, 21); @@ -275,6 +275,12 @@ namespace { if (relative_rank(Us, pos.square(Us)) == RANK_1) kingRing[Us] |= shift(kingRing[Us]); + if (file_of(pos.square(Us)) == FILE_H) + kingRing[Us] |= shift(kingRing[Us]); + + else if (file_of(pos.square(Us)) == FILE_A) + kingRing[Us] |= shift(kingRing[Us]); + kingAttackersCount[Them] = popcount(attackedBy[Us][KING] & pe->pawn_attacks(Them)); kingAttacksCount[Them] = kingAttackersWeight[Them] = 0; } @@ -295,6 +301,7 @@ namespace { Bitboard b, bb; Square s; Score score = SCORE_ZERO; + int mob; attackedBy[Us][Pt] = 0; @@ -319,7 +326,8 @@ namespace { kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]); } - int mob = popcount(b & mobilityArea[Us]); + mob = (Pt == KNIGHT || Pt == BISHOP) ? popcount(b & mobilityArea[Us] & ~pos.pieces(Us, QUEEN)) + : popcount(b & mobilityArea[Us]); mobility[Us] += MobilityBonus[Pt - 2][mob]; @@ -368,7 +376,7 @@ namespace { if (Pt == ROOK) { - // Bonus for aligning rook with with enemy pawns on the same rank/file + // Bonus for aligning rook with enemy pawns on the same rank/file if (relative_rank(Us, s) >= RANK_5) score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]); @@ -406,7 +414,7 @@ namespace { constexpr Color Them = (Us == WHITE ? BLACK : WHITE); constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB - : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB); + : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB); const Square ksq = pos.square(Us); Bitboard weak, b, b1, b2, safe, unsafeChecks, pinned; @@ -513,19 +521,8 @@ namespace { Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safeThreats; Score score = SCORE_ZERO; - // Non-pawn enemies attacked by a pawn + // Non-pawn enemies nonPawnEnemies = pos.pieces(Them) ^ pos.pieces(Them, PAWN); - weak = nonPawnEnemies & attackedBy[Us][PAWN]; - - if (weak) - { - // Our safe or protected pawns - b = pos.pieces(Us, PAWN) - & (~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES]); - - safeThreats = pawn_attacks_bb(b) & weak; - score += ThreatBySafePawn * popcount(safeThreats); - } // Squares strongly protected by the enemy, either because they defend the // square with a pawn, or because they defend the square twice and we don't. @@ -559,17 +556,30 @@ namespace { score += ThreatByRank * (int)relative_rank(Them, s); } - score += Hanging * popcount(weak & ~attackedBy[Them][ALL_PIECES]); - b = weak & attackedBy[Us][KING]; if (b) score += ThreatByKing[more_than_one(b)]; + + score += Hanging * popcount(weak & ~attackedBy[Them][ALL_PIECES]); + + // Bonus for overload (non-pawn enemies attacked and defended exactly once) + b = nonPawnEnemies + & attackedBy[Us][ALL_PIECES] & ~attackedBy2[Us] + & attackedBy[Them][ALL_PIECES] & ~attackedBy2[Them]; + score += Overload * popcount(b); } // Bonus for enemy unopposed weak pawns if (pos.pieces(Us, ROOK, QUEEN)) score += WeakUnopposedPawn * pe->weak_unopposed(Them); + // Our safe or protected pawns + b = pos.pieces(Us, PAWN) + & (~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES]); + + safeThreats = pawn_attacks_bb(b) & nonPawnEnemies; + score += ThreatBySafePawn * popcount(safeThreats); + // 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(); @@ -687,7 +697,7 @@ namespace { } else if (pos.pieces(Us) & blockSq) bonus += make_score(w + r * 2, w + r * 2); - } // rr != 0 + } // w != 0 // Scale down bonus for candidate passers which need more than one // pawn push to become passed or have a pawn in front of them. @@ -728,8 +738,7 @@ namespace { // pawn, or if it is undefended and attacked by an enemy piece. Bitboard safe = SpaceMask & ~pos.pieces(Us, PAWN) - & ~attackedBy[Them][PAWN] - & (attackedBy[Us][ALL_PIECES] | ~attackedBy[Them][ALL_PIECES]); + & ~attackedBy[Them][PAWN]; // Find all squares which are at most three squares behind some friendly pawn Bitboard behind = pos.pieces(Us, PAWN); @@ -795,11 +804,10 @@ namespace { { if (pos.opposite_bishops()) { - // Endgame with opposite-colored bishops and no other pieces (ignoring pawns) - // is almost a draw, in case of KBP vs KB, it is even more a draw. + // Endgame with opposite-colored bishops and no other pieces is almost a draw if ( pos.non_pawn_material(WHITE) == BishopValueMg && pos.non_pawn_material(BLACK) == BishopValueMg) - sf = more_than_one(pos.pieces(PAWN)) ? 31 : 9; + sf = 31; // Endgame with opposite-colored bishops, but also other pieces. Still // a bit drawish, but not as drawish as with only the two bishops. @@ -838,7 +846,7 @@ namespace { // Initialize score by reading the incrementally updated scores included in // the position object (material + piece square tables) and the material // imbalance. Score is computed internally from the white point of view. - Score score = pos.psq_score() + me->imbalance() + Eval::Contempt; + Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt; // Probe the pawn hash table pe = Pawns::probe(pos); @@ -909,7 +917,7 @@ std::string Eval::trace(const Position& pos) { std::memset(scores, 0, sizeof(scores)); - Eval::Contempt = SCORE_ZERO; // Reset any dynamic contempt + pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt Value v = Evaluation(pos).value();