X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fevaluate.cpp;h=7359eb92b35db5e36ac55d068076161b5590eba8;hb=dc243a3c880d0a736fb93848cf56e3221e07f8a3;hp=7e6260c8a34128fe588b3a2c492e07af526986b1;hpb=9a11a291942a8a7b1ebb36282c666ca8d1be1892;p=stockfish
diff --git a/src/evaluate.cpp b/src/evaluate.cpp
index 7e6260c8..7359eb92 100644
--- a/src/evaluate.cpp
+++ b/src/evaluate.cpp
@@ -18,6 +18,7 @@
along with this program. If not, see .
*/
+#include
#include
#include // For std::memset
#include
@@ -73,7 +74,7 @@ using namespace Trace;
namespace {
// Threshold for lazy and space evaluation
- constexpr Value LazyThreshold = Value(1500);
+ constexpr Value LazyThreshold = Value(1400);
constexpr Value SpaceThreshold = Value(12222);
// KingAttackWeights[PieceType] contains king attack weights by piece type
@@ -122,13 +123,7 @@ namespace {
// PassedRank[Rank] contains a bonus according to the rank of a passed pawn
constexpr Score PassedRank[RANK_NB] = {
- S(0, 0), S(5, 18), S(12, 23), S(10, 31), S(57, 62), S(163, 167), S(271, 250)
- };
-
- // PassedFile[File] contains a bonus according to the file of a passed pawn
- constexpr Score PassedFile[FILE_NB] = {
- S( -1, 7), S( 0, 9), S(-9, -8), S(-30,-14),
- S(-30,-14), S(-9, -8), S( 0, 9), S( -1, 7)
+ S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
};
// Assorted bonuses and penalties
@@ -140,7 +135,8 @@ namespace {
constexpr Score KnightOnQueen = S( 16, 12);
constexpr Score LongDiagonalBishop = S( 45, 0);
constexpr Score MinorBehindPawn = S( 18, 3);
- constexpr Score Outpost = S( 9, 3);
+ constexpr Score Outpost = S( 18, 6);
+ constexpr Score PassedFile = S( 11, 8);
constexpr Score PawnlessFlank = S( 17, 95);
constexpr Score RestrictedPiece = S( 7, 7);
constexpr Score RookOnPawn = S( 10, 32);
@@ -151,7 +147,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
@@ -186,15 +181,12 @@ namespace {
// is also calculated is ALL_PIECES.
Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
- // attackedBy2[color] are the squares attacked by 2 pieces of a given color,
- // possibly via x-ray or by one pawn and one piece. Diagonal x-ray through
- // pawn or squares attacked by 2 pawns are not explicitly added.
+ // attackedBy2[color] are the squares attacked by at least 2 units of a given
+ // 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 +216,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);
@@ -241,8 +233,7 @@ namespace {
attackedBy[Us][KING] = pos.attacks_from(ksq);
attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
- attackedBy2[Us] = (attackedBy[Us][KING] & attackedBy[Us][PAWN])
- | dblAttackByPawn;
+ attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
// Init our king safety tables
kingRing[Us] = attackedBy[Us][KING];
@@ -306,14 +297,12 @@ namespace {
if (Pt == BISHOP || Pt == KNIGHT)
{
// Bonus if piece is on an outpost square or can reach one
- bb = OutpostRanks & ~pe->pawn_attacks_span(Them);
+ bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
if (bb & s)
- score += Outpost * (Pt == KNIGHT ? 4 : 2)
- * (1 + bool(attackedBy[Us][PAWN] & s));
+ score += Outpost * (Pt == KNIGHT ? 4 : 2);
- else if (bb &= b & ~pos.pieces(Us))
- score += Outpost * (Pt == KNIGHT ? 2 : 1)
- * (1 + bool(attackedBy[Us][PAWN] & bb));
+ else if (bb & b & ~pos.pieces(Us))
+ score += Outpost * (Pt == KNIGHT ? 2 : 1);
// Knight and Bishop bonus for being right behind a pawn
if (shift(pos.pieces(PAWN)) & s)
@@ -358,8 +347,8 @@ namespace {
score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]);
// Bonus for rook on an open or semi-open file
- if (pos.semiopen_file(Us, file_of(s)))
- score += RookOnFile[bool(pos.semiopen_file(Them, file_of(s)))];
+ if (pos.is_on_semiopen_file(Us, s))
+ score += RookOnFile[bool(pos.is_on_semiopen_file(Them, s))];
// Penalty when trapped by the king, even more if the king cannot castle
else if (mob <= 3)
@@ -558,10 +547,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();
@@ -570,7 +555,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
@@ -614,7 +599,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);
@@ -626,12 +611,13 @@ namespace {
assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
int r = relative_rank(Us, s);
+ File f = file_of(s);
Score bonus = PassedRank[r];
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
@@ -645,42 +631,37 @@ 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) & pos.attacks_from(s);
-
- if (!(pos.pieces(Us) & bb))
- defendedSquares &= attackedBy[Us][ALL_PIECES];
+ bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
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;
+ unsafeSquares &= attackedBy[Them][ALL_PIECES];
- // If the path to the queen is fully defended, assign a big bonus.
- // Otherwise assign a smaller bonus if the block square is defended.
- if (defendedSquares == squaresToQueen)
- k += 6;
+ // 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 ;
- else if (defendedSquares & blockSq)
- k += 4;
+ // 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);
}
- } // rank > RANK_3
+ } // r > RANK_3
// 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)];
+ score += bonus - PassedFile * std::min(f, ~f);
}
if (T)
@@ -717,12 +698,10 @@ namespace {
// Find all squares which are at most three squares behind some friendly pawn
Bitboard behind = pos.pieces(Us, PAWN);
behind |= shift(behind);
- behind |= shift(shift(behind));
-
- int bonus = popcount(safe) + popcount(behind & safe);
- int weight = pos.count(Us)
- - (16 - pos.count()) / 4;
+ behind |= shift(behind);
+ int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
+ int weight = pos.count(Us) - 1;
Score score = make_score(bonus * weight * weight / 16, 0);
if (T)
@@ -777,8 +756,7 @@ namespace {
if (sf == SCALE_FACTOR_NORMAL)
{
if ( pos.opposite_bishops()
- && pos.non_pawn_material(WHITE) == BishopValueMg
- && pos.non_pawn_material(BLACK) == BishopValueMg)
+ && 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);
@@ -817,7 +795,7 @@ namespace {
// Early exit if score is high
Value v = (mg_value(score) + eg_value(score)) / 2;
- if (abs(v) > LazyThreshold)
+ if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64)
return pos.side_to_move() == WHITE ? v : -v;
// Main evaluation begins here