X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=9a67a8e429024aa8f5453281c450aacbe322028d;hp=30c22a8e65b340103fda85698f31d91e55dfcc97;hb=13ba67801f0331e3ffde23794b989765af5a9aa2;hpb=09caea5cab0b6c23fea8347a740bcc00083da6ab diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 30c22a8e..9a67a8e4 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -133,6 +133,7 @@ namespace { }; // Assorted bonuses and penalties + constexpr Score AttacksOnSpaceArea = S( 4, 0); constexpr Score BishopPawns = S( 3, 7); constexpr Score CorneredBishop = S( 50, 50); constexpr Score FlankAttacks = S( 8, 0); @@ -141,7 +142,7 @@ namespace { constexpr Score KnightOnQueen = S( 16, 12); constexpr Score LongDiagonalBishop = S( 45, 0); constexpr Score MinorBehindPawn = S( 18, 3); - constexpr Score Outpost = S( 36, 12); + constexpr Score Outpost = S( 18, 6); constexpr Score PawnlessFlank = S( 17, 95); constexpr Score RestrictedPiece = S( 7, 7); constexpr Score RookOnPawn = S( 10, 32); @@ -152,7 +153,6 @@ namespace { constexpr Score ThreatBySafePawn = S(173, 94); constexpr Score TrappedRook = S( 47, 4); constexpr Score WeakQueen = S( 49, 15); - constexpr Score WeakUnopposedPawn = S( 12, 23); #undef S @@ -191,10 +191,8 @@ namespace { // color, including x-rays. But diagonal x-rays through pawns are not computed. Bitboard attackedBy2[COLOR_NB]; - // kingRing[color] are the squares adjacent to the king, plus (only for a - // king on its first rank) the squares two ranks in front. For instance, - // if black's king is on g8, kingRing[BLACK] is f8, h8, f7, g7, h7, f6, g6 - // and h6. + // kingRing[color] are the squares adjacent to the king plus some other + // very near squares, depending on king position. Bitboard kingRing[COLOR_NB]; // kingAttackersCount[color] is the number of pieces of the given color @@ -224,7 +222,7 @@ namespace { constexpr Color Them = (Us == WHITE ? BLACK : WHITE); constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH); constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH); - constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB: Rank7BB | Rank6BB); + constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB); const Square ksq = pos.square(Us); @@ -307,10 +305,10 @@ namespace { // Bonus if piece is on an outpost square or can reach one bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them); if (bb & s) - score += Outpost * (Pt == KNIGHT ? 2 : 1); + score += Outpost * (Pt == KNIGHT ? 4 : 2); else if (bb & b & ~pos.pieces(Us)) - score += Outpost / (Pt == KNIGHT ? 1 : 2); + score += Outpost * (Pt == KNIGHT ? 2 : 1); // Knight and Bishop bonus for being right behind a pawn if (shift(pos.pieces(PAWN)) & s) @@ -555,10 +553,6 @@ namespace { score += RestrictedPiece * popcount(b); - // Bonus for enemy unopposed weak pawns - if (pos.pieces(Us, ROOK, QUEEN)) - score += WeakUnopposedPawn * pe->weak_unopposed(Them); - // 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(); @@ -567,7 +561,7 @@ namespace { b &= ~attackedBy[Them][PAWN] & safe; // Bonus for safe pawn threats on the next move - b = pawn_attacks_bb(b) & pos.pieces(Them); + b = pawn_attacks_bb(b) & nonPawnEnemies; score += ThreatByPawnPush * popcount(b); // Our safe or protected pawns @@ -611,7 +605,7 @@ namespace { return std::min(distance(pos.square(c), s), 5); }; - Bitboard b, bb, squaresToQueen, defendedSquares, unsafeSquares; + Bitboard b, bb, squaresToQueen, unsafeSquares; Score score = SCORE_ZERO; b = pe->passed_pawns(Us); @@ -628,7 +622,7 @@ namespace { if (r > RANK_3) { - int w = (r-2) * (r-2) + 2; + int w = 5 * r - 13; Square blockSq = s + Up; // Adjust bonus based on the king's proximity @@ -642,25 +636,24 @@ namespace { // If the pawn is free to advance, then increase the bonus if (pos.empty(blockSq)) { - // If there is a rook or queen attacking/defending the pawn from behind, - // consider all the squaresToQueen. Otherwise consider only the squares - // in the pawn's path attacked or occupied by the enemy. - defendedSquares = unsafeSquares = squaresToQueen = forward_file_bb(Us, s); + squaresToQueen = forward_file_bb(Us, s); + unsafeSquares = passed_pawn_span(Us, s); bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN); - if (!(pos.pieces(Us) & bb)) - defendedSquares &= attackedBy[Us][ALL_PIECES]; - if (!(pos.pieces(Them) & bb)) unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them); - // If there aren't any enemy attacks, assign a big bonus. Otherwise - // assign a smaller bonus if the block square isn't attacked. - int k = !unsafeSquares ? 20 : !(unsafeSquares & blockSq) ? 9 : 0; + // If there are no enemy attacks on passed pawn span, assign a big bonus. + // Otherwise assign a smaller bonus if the path to queen is not attacked + // and even smaller bonus if it is attacked but block square is not. + int k = !unsafeSquares ? 35 : + !(unsafeSquares & squaresToQueen) ? 20 : + !(unsafeSquares & blockSq) ? 9 : + 0 ; - // Assign a larger bonus if the block square is defended. - if (defendedSquares & blockSq) + // Assign a larger bonus if the block square is defended + if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq)) k += 5; bonus += make_score(k * w, k * w); @@ -670,7 +663,7 @@ namespace { // Scale down bonus for candidate passers which need more than one // pawn push to become passed, or have a pawn in front of them. if ( !pos.pawn_passed(Us, s + Up) - || (pos.pieces(PAWN) & forward_file_bb(Us, s))) + || (pos.pieces(PAWN) & (s + Up))) bonus = bonus / 2; score += bonus + PassedFile[file_of(s)]; @@ -716,6 +709,8 @@ namespace { int weight = pos.count(Us) - 1; Score score = make_score(bonus * weight * weight / 16, 0); + score -= AttacksOnSpaceArea * popcount(attackedBy[Them][ALL_PIECES] & behind & safe); + if (T) Trace::add(SPACE, Us, score); @@ -807,7 +802,7 @@ namespace { // Early exit if score is high Value v = (mg_value(score) + eg_value(score)) / 2; - if (abs(v) > (LazyThreshold + pos.non_pawn_material() / 64)) + if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64) return pos.side_to_move() == WHITE ? v : -v; // Main evaluation begins here