mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-20 17:16:33 +08:00
Simplify outpost code
Also inline defintions of SpaceMask and CenterBindMask. Verified from assembly that compiler computes the values at compile time, so it is also theoretical faster. While there factor out scale factor evaluation. No functional change.
This commit is contained in:
164
src/evaluate.cpp
164
src/evaluate.cpp
@@ -102,6 +102,7 @@ namespace {
|
|||||||
int kingAdjacentZoneAttacksCount[COLOR_NB];
|
int kingAdjacentZoneAttacksCount[COLOR_NB];
|
||||||
|
|
||||||
Bitboard pinnedPieces[COLOR_NB];
|
Bitboard pinnedPieces[COLOR_NB];
|
||||||
|
Material::Entry* me;
|
||||||
Pawns::Entry* pi;
|
Pawns::Entry* pi;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -141,11 +142,6 @@ namespace {
|
|||||||
S(112,125), S(113,127), S(117,137), S(122,143) }
|
S(112,125), S(113,127), S(117,137), S(122,143) }
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mask of allowed outpost squares indexed by color
|
|
||||||
const Bitboard OutpostMask[COLOR_NB] = {
|
|
||||||
Rank4BB | Rank5BB | Rank6BB, Rank5BB | Rank4BB | Rank3BB
|
|
||||||
};
|
|
||||||
|
|
||||||
// Outpost[knight/bishop][supported by pawn] contains bonuses for knights and
|
// Outpost[knight/bishop][supported by pawn] contains bonuses for knights and
|
||||||
// bishops outposts, bigger if outpost piece is supported by a pawn.
|
// bishops outposts, bigger if outpost piece is supported by a pawn.
|
||||||
const Score Outpost[][2] = {
|
const Score Outpost[][2] = {
|
||||||
@@ -153,8 +149,9 @@ namespace {
|
|||||||
{ S(18, 5), S(27, 8) } // Bishops
|
{ S(18, 5), S(27, 8) } // Bishops
|
||||||
};
|
};
|
||||||
|
|
||||||
// ReachableOutpost[knight/bishop][supported by pawn] contains bonuses for knights and
|
// ReachableOutpost[knight/bishop][supported by pawn] contains bonuses for
|
||||||
// bishops which can reach a outpost square in one move, bigger if outpost square is supported by a pawn.
|
// knights and bishops which can reach an outpost square in one move, bigger
|
||||||
|
// if outpost square is supported by a pawn.
|
||||||
const Score ReachableOutpost[][2] = {
|
const Score ReachableOutpost[][2] = {
|
||||||
{ S(21, 5), S(31, 8) }, // Knights
|
{ S(21, 5), S(31, 8) }, // Knights
|
||||||
{ S( 8, 2), S(13, 4) } // Bishops
|
{ S( 8, 2), S(13, 4) } // Bishops
|
||||||
@@ -174,7 +171,7 @@ namespace {
|
|||||||
S(0, 0), S(0, 0), S(107, 138), S(84, 122), S(114, 203), S(121, 217)
|
S(0, 0), S(0, 0), S(107, 138), S(84, 122), S(114, 203), S(121, 217)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Passed[mg/eg][rank] contains midgame and endgame bonuses for passed pawns.
|
// Passed[mg/eg][Rank] contains midgame and endgame bonuses for passed pawns.
|
||||||
// We don't use a Score because we process the two components independently.
|
// We don't use a Score because we process the two components independently.
|
||||||
const Value Passed[][RANK_NB] = {
|
const Value Passed[][RANK_NB] = {
|
||||||
{ V(0), V( 1), V(34), V(90), V(214), V(328) },
|
{ V(0), V( 1), V(34), V(90), V(214), V(328) },
|
||||||
@@ -211,15 +208,6 @@ namespace {
|
|||||||
#undef S
|
#undef S
|
||||||
#undef V
|
#undef V
|
||||||
|
|
||||||
// SpaceMask[Color] contains the area of the board which is considered
|
|
||||||
// by the space evaluation. In the middlegame, each side is given a bonus
|
|
||||||
// based on how many squares inside this area are safe and available for
|
|
||||||
// friendly minor pieces.
|
|
||||||
const Bitboard SpaceMask[COLOR_NB] = {
|
|
||||||
(FileCBB | FileDBB | FileEBB | FileFBB) & (Rank2BB | Rank3BB | Rank4BB),
|
|
||||||
(FileCBB | FileDBB | FileEBB | FileFBB) & (Rank7BB | Rank6BB | Rank5BB)
|
|
||||||
};
|
|
||||||
|
|
||||||
// King danger constants and variables. The king danger scores are looked-up
|
// King danger constants and variables. The king danger scores are looked-up
|
||||||
// in KingDanger[]. Various little "meta-bonuses" measuring the strength
|
// in KingDanger[]. Various little "meta-bonuses" measuring the strength
|
||||||
// of the enemy attack are added up into an integer, which is used as an
|
// of the enemy attack are added up into an integer, which is used as an
|
||||||
@@ -237,11 +225,11 @@ namespace {
|
|||||||
const int KnightCheck = 14;
|
const int KnightCheck = 14;
|
||||||
|
|
||||||
|
|
||||||
// init_eval_info() initializes king bitboards for given color adding
|
// eval_init() initializes king and attack bitboards for given color
|
||||||
// pawn attacks. To be done at the beginning of the evaluation.
|
// adding pawn attacks. To be done at the beginning of the evaluation.
|
||||||
|
|
||||||
template<Color Us>
|
template<Color Us>
|
||||||
void init_eval_info(const Position& pos, EvalInfo& ei) {
|
void eval_init(const Position& pos, EvalInfo& ei) {
|
||||||
|
|
||||||
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
const Square Down = (Us == WHITE ? DELTA_S : DELTA_N);
|
const Square Down = (Us == WHITE ? DELTA_S : DELTA_N);
|
||||||
@@ -264,17 +252,20 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// evaluate_pieces() assigns bonuses and penalties to the pieces of a given color
|
// evaluate_pieces() assigns bonuses and penalties to the pieces of a given
|
||||||
|
// color and type.
|
||||||
template<PieceType Pt, Color Us, bool DoTrace>
|
|
||||||
Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility, const Bitboard* mobilityArea) {
|
|
||||||
|
|
||||||
|
template<bool DoTrace, Color Us = WHITE, PieceType Pt = KNIGHT>
|
||||||
|
Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility,
|
||||||
|
const Bitboard* mobilityArea) {
|
||||||
Bitboard b, bb;
|
Bitboard b, bb;
|
||||||
Square s;
|
Square s;
|
||||||
Score score = SCORE_ZERO;
|
Score score = SCORE_ZERO;
|
||||||
|
|
||||||
const PieceType NextPt = (Us == WHITE ? Pt : PieceType(Pt + 1));
|
const PieceType NextPt = (Us == WHITE ? Pt : PieceType(Pt + 1));
|
||||||
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
|
const Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
|
||||||
|
: Rank5BB | Rank4BB | Rank3BB);
|
||||||
const Square* pl = pos.squares<Pt>(Us);
|
const Square* pl = pos.squares<Pt>(Us);
|
||||||
|
|
||||||
ei.attackedBy[Us][Pt] = 0;
|
ei.attackedBy[Us][Pt] = 0;
|
||||||
@@ -312,7 +303,7 @@ namespace {
|
|||||||
if (Pt == BISHOP || Pt == KNIGHT)
|
if (Pt == BISHOP || Pt == KNIGHT)
|
||||||
{
|
{
|
||||||
// Bonus for outpost squares
|
// Bonus for outpost squares
|
||||||
bb = OutpostMask[Us] & ~ei.pi->pawn_attacks_span(Them);
|
bb = OutpostRanks & ~ei.pi->pawn_attacks_span(Them);
|
||||||
if (bb & s)
|
if (bb & s)
|
||||||
score += Outpost[Pt == BISHOP][!!(ei.attackedBy[Us][PAWN] & s)];
|
score += Outpost[Pt == BISHOP][!!(ei.attackedBy[Us][PAWN] & s)];
|
||||||
else
|
else
|
||||||
@@ -377,13 +368,13 @@ namespace {
|
|||||||
Trace::add(Pt, Us, score);
|
Trace::add(Pt, Us, score);
|
||||||
|
|
||||||
// Recursively call evaluate_pieces() of next piece type until KING excluded
|
// Recursively call evaluate_pieces() of next piece type until KING excluded
|
||||||
return score - evaluate_pieces<NextPt, Them, DoTrace>(pos, ei, mobility, mobilityArea);
|
return score - evaluate_pieces<DoTrace, Them, NextPt>(pos, ei, mobility, mobilityArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
Score evaluate_pieces<KING, WHITE, false>(const Position&, EvalInfo&, Score*, const Bitboard*) { return SCORE_ZERO; }
|
Score evaluate_pieces<false, WHITE, KING>(const Position&, EvalInfo&, Score*, const Bitboard*) { return SCORE_ZERO; }
|
||||||
template<>
|
template<>
|
||||||
Score evaluate_pieces<KING, WHITE, true>(const Position&, EvalInfo&, Score*, const Bitboard*) { return SCORE_ZERO; }
|
Score evaluate_pieces< true, WHITE, KING>(const Position&, EvalInfo&, Score*, const Bitboard*) { return SCORE_ZERO; }
|
||||||
|
|
||||||
|
|
||||||
// evaluate_king() assigns bonuses and penalties to a king of a given color
|
// evaluate_king() assigns bonuses and penalties to a king of a given color
|
||||||
@@ -404,7 +395,7 @@ namespace {
|
|||||||
if (ei.kingAttackersCount[Them])
|
if (ei.kingAttackersCount[Them])
|
||||||
{
|
{
|
||||||
// Find the attacked squares around the king which have no defenders
|
// Find the attacked squares around the king which have no defenders
|
||||||
// apart from the king itself
|
// apart from the king itself.
|
||||||
undefended = ei.attackedBy[Them][ALL_PIECES]
|
undefended = ei.attackedBy[Them][ALL_PIECES]
|
||||||
& ei.attackedBy[Us][KING]
|
& ei.attackedBy[Us][KING]
|
||||||
& ~( ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT]
|
& ~( ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT]
|
||||||
@@ -665,11 +656,14 @@ namespace {
|
|||||||
Score evaluate_space(const Position& pos, const EvalInfo& ei) {
|
Score evaluate_space(const Position& pos, const EvalInfo& ei) {
|
||||||
|
|
||||||
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
const Color Them = (Us == WHITE ? BLACK : WHITE);
|
||||||
|
const Bitboard SpaceMask =
|
||||||
|
Us == WHITE ? (FileCBB | FileDBB | FileEBB | FileFBB) & (Rank2BB | Rank3BB | Rank4BB)
|
||||||
|
: (FileCBB | FileDBB | FileEBB | FileFBB) & (Rank7BB | Rank6BB | Rank5BB);
|
||||||
|
|
||||||
// Find the safe squares for our pieces inside the area defined by
|
// Find the safe squares for our pieces inside the area defined by
|
||||||
// SpaceMask[]. A square is unsafe if it is attacked by an enemy
|
// SpaceMask. A square is unsafe if it is attacked by an enemy
|
||||||
// pawn, or if it is undefended and attacked by an enemy piece.
|
// pawn, or if it is undefended and attacked by an enemy piece.
|
||||||
Bitboard safe = SpaceMask[Us]
|
Bitboard safe = SpaceMask
|
||||||
& ~pos.pieces(Us, PAWN)
|
& ~pos.pieces(Us, PAWN)
|
||||||
& ~ei.attackedBy[Them][PAWN]
|
& ~ei.attackedBy[Them][PAWN]
|
||||||
& (ei.attackedBy[Us][ALL_PIECES] | ~ei.attackedBy[Them][ALL_PIECES]);
|
& (ei.attackedBy[Us][ALL_PIECES] | ~ei.attackedBy[Them][ALL_PIECES]);
|
||||||
@@ -710,11 +704,47 @@ namespace {
|
|||||||
return make_score(0, value);
|
return make_score(0, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// evaluate_scale_factor() computes the scale factor for the winning side
|
||||||
|
ScaleFactor evaluate_scale_factor(const Position& pos, const EvalInfo& ei, Score score) {
|
||||||
|
|
||||||
|
Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK;
|
||||||
|
ScaleFactor sf = ei.me->scale_factor(pos, strongSide);
|
||||||
|
|
||||||
|
// If we don't already have an unusual scale factor, check for certain
|
||||||
|
// types of endgames, and use a lower scale for those.
|
||||||
|
if ( ei.me->game_phase() < PHASE_MIDGAME
|
||||||
|
&& (sf == SCALE_FACTOR_NORMAL || sf == SCALE_FACTOR_ONEPAWN))
|
||||||
|
{
|
||||||
|
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 is even more a draw.
|
||||||
|
if ( pos.non_pawn_material(WHITE) == BishopValueMg
|
||||||
|
&& pos.non_pawn_material(BLACK) == BishopValueMg)
|
||||||
|
sf = more_than_one(pos.pieces(PAWN)) ? ScaleFactor(31) : ScaleFactor(9);
|
||||||
|
|
||||||
|
// Endgame with opposite-colored bishops, but also other pieces. Still
|
||||||
|
// a bit drawish, but not as drawish as with only the two bishops.
|
||||||
|
else
|
||||||
|
sf = ScaleFactor(46 * sf / SCALE_FACTOR_NORMAL);
|
||||||
|
}
|
||||||
|
// Endings where weaker side can place his king in front of the opponent's
|
||||||
|
// pawns are drawish.
|
||||||
|
else if ( abs(eg_value(score)) <= BishopValueEg
|
||||||
|
&& ei.pi->pawn_span(strongSide) <= 1
|
||||||
|
&& !pos.pawn_passed(~strongSide, pos.square<KING>(~strongSide)))
|
||||||
|
sf = ei.pi->pawn_span(strongSide) ? ScaleFactor(51) : ScaleFactor(37);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sf;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
/// evaluate() is the main evaluation function. It returns a static evaluation
|
/// evaluate() is the main evaluation function. It returns a static evaluation
|
||||||
/// of the position always from the point of view of the side to move.
|
/// of the position from the point of view of the side to move.
|
||||||
|
|
||||||
template<bool DoTrace>
|
template<bool DoTrace>
|
||||||
Value Eval::evaluate(const Position& pos) {
|
Value Eval::evaluate(const Position& pos) {
|
||||||
@@ -724,19 +754,19 @@ Value Eval::evaluate(const Position& pos) {
|
|||||||
EvalInfo ei;
|
EvalInfo ei;
|
||||||
Score score, mobility[2] = { SCORE_ZERO, SCORE_ZERO };
|
Score score, mobility[2] = { SCORE_ZERO, SCORE_ZERO };
|
||||||
|
|
||||||
// Initialize score by reading the incrementally updated scores included
|
// Initialize score by reading the incrementally updated scores included in
|
||||||
// in the position object (material + piece square tables).
|
// the position object (material + piece square tables). Score is computed
|
||||||
// Score is computed from the point of view of white.
|
// internally from the white point of view.
|
||||||
score = pos.psq_score();
|
score = pos.psq_score();
|
||||||
|
|
||||||
// Probe the material hash table
|
// Probe the material hash table
|
||||||
Material::Entry* me = Material::probe(pos);
|
ei.me = Material::probe(pos);
|
||||||
score += me->imbalance();
|
score += ei.me->imbalance();
|
||||||
|
|
||||||
// If we have a specialized evaluation function for the current material
|
// If we have a specialized evaluation function for the current material
|
||||||
// configuration, call it and return.
|
// configuration, call it and return.
|
||||||
if (me->specialized_eval_exists())
|
if (ei.me->specialized_eval_exists())
|
||||||
return me->evaluate(pos);
|
return ei.me->evaluate(pos);
|
||||||
|
|
||||||
// Probe the pawn hash table
|
// Probe the pawn hash table
|
||||||
ei.pi = Pawns::probe(pos);
|
ei.pi = Pawns::probe(pos);
|
||||||
@@ -744,27 +774,27 @@ Value Eval::evaluate(const Position& pos) {
|
|||||||
|
|
||||||
// Initialize attack and king safety bitboards
|
// Initialize attack and king safety bitboards
|
||||||
ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[BLACK][ALL_PIECES] = 0;
|
ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[BLACK][ALL_PIECES] = 0;
|
||||||
init_eval_info<WHITE>(pos, ei);
|
eval_init<WHITE>(pos, ei);
|
||||||
init_eval_info<BLACK>(pos, ei);
|
eval_init<BLACK>(pos, ei);
|
||||||
|
|
||||||
// Pawns blocked or on ranks 2 and 3. Will be excluded from the mobility area
|
// Pawns blocked or on ranks 2 and 3 will be excluded from the mobility area
|
||||||
Bitboard blockedPawns[] = {
|
Bitboard blockedPawns[] = {
|
||||||
pos.pieces(WHITE, PAWN) & (shift_bb<DELTA_S>(pos.pieces()) | Rank2BB | Rank3BB),
|
pos.pieces(WHITE, PAWN) & (shift_bb<DELTA_S>(pos.pieces()) | Rank2BB | Rank3BB),
|
||||||
pos.pieces(BLACK, PAWN) & (shift_bb<DELTA_N>(pos.pieces()) | Rank7BB | Rank6BB)
|
pos.pieces(BLACK, PAWN) & (shift_bb<DELTA_N>(pos.pieces()) | Rank7BB | Rank6BB)
|
||||||
};
|
};
|
||||||
|
|
||||||
// Do not include in mobility squares protected by enemy pawns, or occupied
|
// Do not include in mobility area squares protected by enemy pawns, or occupied
|
||||||
// by our blocked pawns or king.
|
// by our blocked pawns or king.
|
||||||
Bitboard mobilityArea[] = {
|
Bitboard mobilityArea[] = {
|
||||||
~(ei.attackedBy[BLACK][PAWN] | blockedPawns[WHITE] | pos.square<KING>(WHITE)),
|
~(ei.attackedBy[BLACK][PAWN] | blockedPawns[WHITE] | pos.square<KING>(WHITE)),
|
||||||
~(ei.attackedBy[WHITE][PAWN] | blockedPawns[BLACK] | pos.square<KING>(BLACK))
|
~(ei.attackedBy[WHITE][PAWN] | blockedPawns[BLACK] | pos.square<KING>(BLACK))
|
||||||
};
|
};
|
||||||
|
|
||||||
// Evaluate pieces and mobility
|
// Evaluate all pieces but king and pawns
|
||||||
score += evaluate_pieces<KNIGHT, WHITE, DoTrace>(pos, ei, mobility, mobilityArea);
|
score += evaluate_pieces<DoTrace>(pos, ei, mobility, mobilityArea);
|
||||||
score += (mobility[WHITE] - mobility[BLACK]) * Weights[Mobility];
|
score += (mobility[WHITE] - mobility[BLACK]) * Weights[Mobility];
|
||||||
|
|
||||||
// Evaluate kings after all other pieces because we need complete attack
|
// Evaluate kings after all other pieces because we need full attack
|
||||||
// information when computing the king safety evaluation.
|
// information when computing the king safety evaluation.
|
||||||
score += evaluate_king<WHITE, DoTrace>(pos, ei)
|
score += evaluate_king<WHITE, DoTrace>(pos, ei)
|
||||||
- evaluate_king<BLACK, DoTrace>(pos, ei);
|
- evaluate_king<BLACK, DoTrace>(pos, ei);
|
||||||
@@ -790,52 +820,26 @@ Value Eval::evaluate(const Position& pos) {
|
|||||||
|
|
||||||
// Evaluate space for both sides, only during opening
|
// Evaluate space for both sides, only during opening
|
||||||
if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 12222)
|
if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 12222)
|
||||||
score += (evaluate_space<WHITE>(pos, ei) - evaluate_space<BLACK>(pos, ei)) * Weights[Space];
|
score += ( evaluate_space<WHITE>(pos, ei)
|
||||||
|
- evaluate_space<BLACK>(pos, ei)) * Weights[Space];
|
||||||
|
|
||||||
// Evaluate position potential for the winning side
|
// Evaluate position potential for the winning side
|
||||||
score += evaluate_initiative(pos, ei.pi->pawn_asymmetry(), eg_value(score));
|
score += evaluate_initiative(pos, ei.pi->pawn_asymmetry(), eg_value(score));
|
||||||
|
|
||||||
// Scale winning side if position is more drawish than it appears
|
// Evaluate scale factor for the winning side
|
||||||
Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK;
|
ScaleFactor sf = evaluate_scale_factor(pos, ei, score);
|
||||||
ScaleFactor sf = me->scale_factor(pos, strongSide);
|
|
||||||
|
|
||||||
// If we don't already have an unusual scale factor, check for certain
|
|
||||||
// types of endgames, and use a lower scale for those.
|
|
||||||
if ( me->game_phase() < PHASE_MIDGAME
|
|
||||||
&& (sf == SCALE_FACTOR_NORMAL || sf == SCALE_FACTOR_ONEPAWN))
|
|
||||||
{
|
|
||||||
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 is even more a draw.
|
|
||||||
if ( pos.non_pawn_material(WHITE) == BishopValueMg
|
|
||||||
&& pos.non_pawn_material(BLACK) == BishopValueMg)
|
|
||||||
sf = more_than_one(pos.pieces(PAWN)) ? ScaleFactor(31) : ScaleFactor(9);
|
|
||||||
|
|
||||||
// Endgame with opposite-colored bishops, but also other pieces. Still
|
|
||||||
// a bit drawish, but not as drawish as with only the two bishops.
|
|
||||||
else
|
|
||||||
sf = ScaleFactor(46 * sf / SCALE_FACTOR_NORMAL);
|
|
||||||
}
|
|
||||||
// Endings where weaker side can place his king in front of the opponent's
|
|
||||||
// pawns are drawish.
|
|
||||||
else if ( abs(eg_value(score)) <= BishopValueEg
|
|
||||||
&& ei.pi->pawn_span(strongSide) <= 1
|
|
||||||
&& !pos.pawn_passed(~strongSide, pos.square<KING>(~strongSide)))
|
|
||||||
sf = ei.pi->pawn_span(strongSide) ? ScaleFactor(51) : ScaleFactor(37);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Interpolate between a middlegame and a (scaled by 'sf') endgame score
|
// Interpolate between a middlegame and a (scaled by 'sf') endgame score
|
||||||
Value v = mg_value(score) * int(me->game_phase())
|
Value v = mg_value(score) * int(ei.me->game_phase())
|
||||||
+ eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
|
+ eg_value(score) * int(PHASE_MIDGAME - ei.me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
|
||||||
|
|
||||||
v /= int(PHASE_MIDGAME);
|
v /= int(PHASE_MIDGAME);
|
||||||
|
|
||||||
// In case of tracing add all single evaluation terms
|
// In case of tracing add all remaining individual evaluation terms
|
||||||
if (DoTrace)
|
if (DoTrace)
|
||||||
{
|
{
|
||||||
Trace::add(MATERIAL, pos.psq_score());
|
Trace::add(MATERIAL, pos.psq_score());
|
||||||
Trace::add(IMBALANCE, me->imbalance());
|
Trace::add(IMBALANCE, ei.me->imbalance());
|
||||||
Trace::add(PAWN, ei.pi->pawns_score());
|
Trace::add(PAWN, ei.pi->pawns_score());
|
||||||
Trace::add(MOBILITY, mobility[WHITE] * Weights[Mobility]
|
Trace::add(MOBILITY, mobility[WHITE] * Weights[Mobility]
|
||||||
, mobility[BLACK] * Weights[Mobility]);
|
, mobility[BLACK] * Weights[Mobility]);
|
||||||
|
|||||||
@@ -57,12 +57,6 @@ namespace {
|
|||||||
// Unsupported pawn penalty
|
// Unsupported pawn penalty
|
||||||
const Score UnsupportedPawnPenalty = S(20, 10);
|
const Score UnsupportedPawnPenalty = S(20, 10);
|
||||||
|
|
||||||
// Center bind bonus: Two pawns controlling the same central square
|
|
||||||
const Bitboard CenterBindMask[COLOR_NB] = {
|
|
||||||
(FileDBB | FileEBB) & (Rank5BB | Rank6BB | Rank7BB),
|
|
||||||
(FileDBB | FileEBB) & (Rank4BB | Rank3BB | Rank2BB)
|
|
||||||
};
|
|
||||||
|
|
||||||
const Score CenterBind = S(16, 0);
|
const Score CenterBind = S(16, 0);
|
||||||
|
|
||||||
// Weakness of our pawn shelter in front of the king by [distance from edge][rank]
|
// Weakness of our pawn shelter in front of the king by [distance from edge][rank]
|
||||||
@@ -106,6 +100,10 @@ namespace {
|
|||||||
const Square Right = (Us == WHITE ? DELTA_NE : DELTA_SW);
|
const Square Right = (Us == WHITE ? DELTA_NE : DELTA_SW);
|
||||||
const Square Left = (Us == WHITE ? DELTA_NW : DELTA_SE);
|
const Square Left = (Us == WHITE ? DELTA_NW : DELTA_SE);
|
||||||
|
|
||||||
|
const Bitboard CenterBindMask =
|
||||||
|
Us == WHITE ? (FileDBB | FileEBB) & (Rank5BB | Rank6BB | Rank7BB)
|
||||||
|
: (FileDBB | FileEBB) & (Rank4BB | Rank3BB | Rank2BB);
|
||||||
|
|
||||||
Bitboard b, neighbours, doubled, supported, phalanx;
|
Bitboard b, neighbours, doubled, supported, phalanx;
|
||||||
Square s;
|
Square s;
|
||||||
bool passed, isolated, opposed, backward, lever, connected;
|
bool passed, isolated, opposed, backward, lever, connected;
|
||||||
@@ -130,9 +128,7 @@ namespace {
|
|||||||
|
|
||||||
File f = file_of(s);
|
File f = file_of(s);
|
||||||
|
|
||||||
// This file cannot be semi-open
|
|
||||||
e->semiopenFiles[Us] &= ~(1 << f);
|
e->semiopenFiles[Us] &= ~(1 << f);
|
||||||
|
|
||||||
e->pawnAttacksSpan[Us] |= pawn_attack_span(Us, s);
|
e->pawnAttacksSpan[Us] |= pawn_attack_span(Us, s);
|
||||||
|
|
||||||
// Flag the pawn
|
// Flag the pawn
|
||||||
@@ -200,7 +196,7 @@ namespace {
|
|||||||
e->pawnSpan[Us] = b ? int(msb(b) - lsb(b)) : 0;
|
e->pawnSpan[Us] = b ? int(msb(b) - lsb(b)) : 0;
|
||||||
|
|
||||||
// Center binds: Two pawns controlling the same central square
|
// Center binds: Two pawns controlling the same central square
|
||||||
b = shift_bb<Right>(ourPawns) & shift_bb<Left>(ourPawns) & CenterBindMask[Us];
|
b = shift_bb<Right>(ourPawns) & shift_bb<Left>(ourPawns) & CenterBindMask;
|
||||||
score += popcount<Max15>(b) * CenterBind;
|
score += popcount<Max15>(b) * CenterBind;
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
|
|||||||
Reference in New Issue
Block a user