mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-25 19:46:55 +08:00
Merge branch 'master' into sf-nnue-update
This commit is contained in:
103
src/evaluate.cpp
103
src/evaluate.cpp
@@ -82,11 +82,11 @@ namespace {
|
||||
// KingAttackWeights[PieceType] contains king attack weights by piece type
|
||||
constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
|
||||
|
||||
// Penalties for enemy's safe checks
|
||||
constexpr int QueenSafeCheck = 772;
|
||||
constexpr int RookSafeCheck = 1084;
|
||||
constexpr int BishopSafeCheck = 645;
|
||||
constexpr int KnightSafeCheck = 792;
|
||||
// SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
|
||||
// higher if multiple safe checks are possible for that piece type.
|
||||
constexpr int SafeCheck[][2] = {
|
||||
{}, {}, {792, 1283}, {645, 967}, {1084, 1897}, {772, 1119}
|
||||
};
|
||||
|
||||
#define S(mg, eg) make_score(mg, eg)
|
||||
|
||||
@@ -108,6 +108,18 @@ namespace {
|
||||
S(110,182), S(114,182), S(114,192), S(116,219) }
|
||||
};
|
||||
|
||||
// KingProtector[knight/bishop] contains penalty for each distance unit to own king
|
||||
constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
|
||||
|
||||
// Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
|
||||
// pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
|
||||
constexpr Score Outpost[] = { S(56, 36), S(30, 23) };
|
||||
|
||||
// PassedRank[Rank] contains a bonus according to the rank of a passed pawn
|
||||
constexpr Score PassedRank[RANK_NB] = {
|
||||
S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
|
||||
};
|
||||
|
||||
// RookOnFile[semiopen/open] contains bonuses for each rook when there is
|
||||
// no (friendly) pawn on the rook file.
|
||||
constexpr Score RookOnFile[] = { S(19, 7), S(48, 29) };
|
||||
@@ -123,23 +135,15 @@ namespace {
|
||||
S(0, 0), S(3, 46), S(37, 68), S(42, 60), S(0, 38), S(58, 41)
|
||||
};
|
||||
|
||||
// PassedRank[Rank] contains a bonus according to the rank of a passed pawn
|
||||
constexpr Score PassedRank[RANK_NB] = {
|
||||
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
|
||||
constexpr Score BishopKingProtector = S( 6, 9);
|
||||
constexpr Score BadOutpost = S( -7, 36);
|
||||
constexpr Score BishopOnKingRing = S( 24, 0);
|
||||
constexpr Score BishopOutpost = S( 30, 23);
|
||||
constexpr Score BishopPawns = S( 3, 7);
|
||||
constexpr Score BishopXRayPawns = S( 4, 5);
|
||||
constexpr Score CorneredBishop = S( 50, 50);
|
||||
constexpr Score FlankAttacks = S( 8, 0);
|
||||
constexpr Score Hanging = S( 69, 36);
|
||||
constexpr Score KnightKingProtector = S( 8, 9);
|
||||
constexpr Score KnightOnQueen = S( 16, 11);
|
||||
constexpr Score KnightOutpost = S( 56, 36);
|
||||
constexpr Score LongDiagonalBishop = S( 45, 0);
|
||||
constexpr Score MinorBehindPawn = S( 18, 3);
|
||||
constexpr Score PassedFile = S( 11, 8);
|
||||
@@ -309,8 +313,14 @@ 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 += (Pt == KNIGHT) ? KnightOutpost : BishopOutpost;
|
||||
if ( Pt == KNIGHT
|
||||
&& bb & s & ~CenterFiles
|
||||
&& !(b & pos.pieces(Them) & ~pos.pieces(PAWN))
|
||||
&& !conditional_more_than_two(
|
||||
pos.pieces(Them) & ~pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide)))
|
||||
score += BadOutpost;
|
||||
else if (bb & s)
|
||||
score += Outpost[Pt == BISHOP];
|
||||
else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
|
||||
score += ReachableOutpost;
|
||||
|
||||
@@ -319,8 +329,7 @@ namespace {
|
||||
score += MinorBehindPawn;
|
||||
|
||||
// Penalty if the piece is far from the king
|
||||
score -= (Pt == KNIGHT ? KnightKingProtector
|
||||
: BishopKingProtector) * distance(pos.square<KING>(Us), s);
|
||||
score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
|
||||
|
||||
if (Pt == BISHOP)
|
||||
{
|
||||
@@ -422,41 +431,33 @@ namespace {
|
||||
b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
|
||||
|
||||
// Enemy rooks checks
|
||||
rookChecks = b1 & safe & attackedBy[Them][ROOK];
|
||||
rookChecks = b1 & attackedBy[Them][ROOK] & safe;
|
||||
if (rookChecks)
|
||||
kingDanger += more_than_one(rookChecks) ? RookSafeCheck * 175/100
|
||||
: RookSafeCheck;
|
||||
kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
|
||||
else
|
||||
unsafeChecks |= b1 & attackedBy[Them][ROOK];
|
||||
|
||||
// Enemy queen safe checks: we count them only if they are from squares from
|
||||
// which we can't give a rook check, because rook checks are more valuable.
|
||||
queenChecks = (b1 | b2)
|
||||
& attackedBy[Them][QUEEN]
|
||||
& safe
|
||||
& ~attackedBy[Us][QUEEN]
|
||||
& ~rookChecks;
|
||||
// Enemy queen safe checks: count them only if the checks are from squares from
|
||||
// which opponent cannot give a rook check, because rook checks are more valuable.
|
||||
queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
|
||||
& ~(attackedBy[Us][QUEEN] | rookChecks);
|
||||
if (queenChecks)
|
||||
kingDanger += more_than_one(queenChecks) ? QueenSafeCheck * 145/100
|
||||
: QueenSafeCheck;
|
||||
kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
|
||||
|
||||
// Enemy bishops checks: we count them only if they are from squares from
|
||||
// which we can't give a queen check, because queen checks are more valuable.
|
||||
bishopChecks = b2
|
||||
& attackedBy[Them][BISHOP]
|
||||
& safe
|
||||
// Enemy bishops checks: count them only if they are from squares from which
|
||||
// opponent cannot give a queen check, because queen checks are more valuable.
|
||||
bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
|
||||
& ~queenChecks;
|
||||
if (bishopChecks)
|
||||
kingDanger += more_than_one(bishopChecks) ? BishopSafeCheck * 3/2
|
||||
: BishopSafeCheck;
|
||||
kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
|
||||
|
||||
else
|
||||
unsafeChecks |= b2 & attackedBy[Them][BISHOP];
|
||||
|
||||
// Enemy knights checks
|
||||
knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
|
||||
if (knightChecks & safe)
|
||||
kingDanger += more_than_one(knightChecks & safe) ? KnightSafeCheck * 162/100
|
||||
: KnightSafeCheck;
|
||||
kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
|
||||
else
|
||||
unsafeChecks |= knightChecks;
|
||||
|
||||
@@ -466,7 +467,7 @@ namespace {
|
||||
b2 = b1 & attackedBy2[Them];
|
||||
b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
|
||||
|
||||
int kingFlankAttack = popcount(b1) + popcount(b2);
|
||||
int kingFlankAttack = popcount(b1) + popcount(b2);
|
||||
int kingFlankDefense = popcount(b3);
|
||||
|
||||
kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
|
||||
@@ -727,9 +728,9 @@ namespace {
|
||||
}
|
||||
|
||||
|
||||
// Evaluation::winnable() adjusts the mg and eg score components based on the
|
||||
// known attacking/defending status of the players. A single value is derived
|
||||
// by interpolation from the mg and eg values and returned.
|
||||
// Evaluation::winnable() adjusts the midgame and endgame score components, based on
|
||||
// the known attacking/defending status of the players. The final value is derived
|
||||
// by interpolation from the midgame and endgame values.
|
||||
|
||||
template<Tracing T>
|
||||
Value Evaluation<T>::winnable(Score score) const {
|
||||
@@ -743,8 +744,8 @@ namespace {
|
||||
bool almostUnwinnable = outflanking < 0
|
||||
&& !pawnsOnBothFlanks;
|
||||
|
||||
bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
|
||||
|| rank_of(pos.square<KING>(BLACK)) < RANK_5;
|
||||
bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
|
||||
|| rank_of(pos.square<KING>(BLACK)) < RANK_5;
|
||||
|
||||
// Compute the initiative bonus for the attacking side
|
||||
int complexity = 9 * pe->passed_count()
|
||||
@@ -769,11 +770,10 @@ namespace {
|
||||
eg += v;
|
||||
|
||||
// Compute the scale factor for the winning side
|
||||
|
||||
Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
|
||||
int sf = me->scale_factor(pos, strongSide);
|
||||
|
||||
// If scale is not already specific, scale down the endgame via general heuristics
|
||||
// If scale factor is not already specific, scale down via general heuristics
|
||||
if (sf == SCALE_FACTOR_NORMAL)
|
||||
{
|
||||
if (pos.opposite_bishops())
|
||||
@@ -784,6 +784,15 @@ namespace {
|
||||
else
|
||||
sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
|
||||
}
|
||||
else if ( pos.non_pawn_material(WHITE) == RookValueMg
|
||||
&& pos.non_pawn_material(BLACK) == RookValueMg
|
||||
&& pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
|
||||
&& bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
|
||||
&& (attackedBy[~strongSide][KING] & pos.pieces(~strongSide, PAWN)))
|
||||
sf = 36;
|
||||
else if (pos.count<QUEEN>() == 1)
|
||||
sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
|
||||
: pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
|
||||
else
|
||||
sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user