const Score RookOpenFile = make_score(43, 21);
const Score RookSemiopenFile = make_score(19, 10);
const Score BishopPawns = make_score( 8, 12);
+ const Score MinorBehindPawn = make_score(16, 0);
const Score UndefendedMinor = make_score(25, 10);
const Score TrappedRook = make_score(90, 0);
Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score& mobility);
template<Color Us, bool Trace>
- Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]);
+ Score evaluate_king(const Position& pos, const EvalInfo& ei, Value margins[]);
template<Color Us, bool Trace>
- Score evaluate_threats(const Position& pos, EvalInfo& ei);
+ Score evaluate_threats(const Position& pos, const EvalInfo& ei);
template<Color Us, bool Trace>
- Score evaluate_passed_pawns(const Position& pos, EvalInfo& ei);
+ Score evaluate_passed_pawns(const Position& pos, const EvalInfo& ei);
template<Color Us>
- int evaluate_space(const Position& pos, EvalInfo& ei);
+ int evaluate_space(const Position& pos, const EvalInfo& ei);
- Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei);
+ Score evaluate_unstoppable_pawns(const Position& pos, const EvalInfo& ei);
Value interpolate(const Score& v, Phase ph, ScaleFactor sf);
Score apply_weight(Score v, Score w);
if (!(pos.pieces(Them, PAWN) & pawn_attack_span(Us, s)))
score += evaluate_outposts<Piece, Us>(pos, ei, s);
- // Pawn in front of knight/bishop
+ // Bishop or knight behind a pawn
if ( relative_rank(Us, s) < RANK_5
&& (pos.pieces(PAWN) & (s + pawn_push(Us))))
- score += make_score(16, 0);
+ score += MinorBehindPawn;
}
if ( (Piece == ROOK || Piece == QUEEN)
// and the type of attacked one.
template<Color Us, bool Trace>
- Score evaluate_threats(const Position& pos, EvalInfo& ei) {
+ Score evaluate_threats(const Position& pos, const EvalInfo& ei) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
// evaluate_king<>() assigns bonuses and penalties to a king of a given color
template<Color Us, bool Trace>
- Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]) {
+ Score evaluate_king(const Position& pos, const EvalInfo& ei, Value margins[]) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
// evaluate_passed_pawns<>() evaluates the passed pawns of the given color
template<Color Us, bool Trace>
- Score evaluate_passed_pawns(const Position& pos, EvalInfo& ei) {
+ Score evaluate_passed_pawns(const Position& pos, const EvalInfo& ei) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
if (pos.is_empty(blockSq))
{
squaresToQueen = forward_bb(Us, s);
- defendedSquares = squaresToQueen & ei.attackedBy[Us][ALL_PIECES];
// If there is an enemy rook or queen attacking the pawn from behind,
// add all X-ray attacks by the rook or queen. Otherwise consider only
else
unsafeSquares = squaresToQueen & (ei.attackedBy[Them][ALL_PIECES] | pos.pieces(Them));
+ if ( unlikely(forward_bb(Them, s) & pos.pieces(Us, ROOK, QUEEN))
+ && (forward_bb(Them, s) & pos.pieces(Us, ROOK, QUEEN) & pos.attacks_from<ROOK>(s)))
+ defendedSquares = squaresToQueen;
+ else
+ defendedSquares = squaresToQueen & ei.attackedBy[Us][ALL_PIECES];
+
// If there aren't enemy attacks huge bonus, a bit smaller if at
// least block square is not attacked, otherwise smallest bonus.
int k = !unsafeSquares ? 15 : !(unsafeSquares & blockSq) ? 9 : 3;
// evaluate_unstoppable_pawns() evaluates the unstoppable passed pawns for both sides, this is quite
// conservative and returns a winning score only when we are very sure that the pawn is winning.
- Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei) {
+ Score evaluate_unstoppable_pawns(const Position& pos, const EvalInfo& ei) {
Bitboard b, b2, blockers, supporters, queeningPath, candidates;
Square s, blockSq, queeningSquare;
// twice. Finally, the space bonus is scaled by a weight taken from the
// material hash table. The aim is to improve play on game opening.
template<Color Us>
- int evaluate_space(const Position& pos, EvalInfo& ei) {
+ int evaluate_space(const Position& pos, const EvalInfo& ei) {
const Color Them = (Us == WHITE ? BLACK : WHITE);
assert(eg_value(v) > -VALUE_INFINITE && eg_value(v) < VALUE_INFINITE);
assert(ph >= PHASE_ENDGAME && ph <= PHASE_MIDGAME);
- int ev = (eg_value(v) * int(sf)) / SCALE_FACTOR_NORMAL;
- int result = (mg_value(v) * int(ph) + ev * int(128 - ph)) / 128;
- return Value((result / GrainSize) * GrainSize); // Sign independent
+ int e = (eg_value(v) * int(sf)) / SCALE_FACTOR_NORMAL;
+ int r = (mg_value(v) * int(ph) + e * int(PHASE_MIDGAME - ph)) / PHASE_MIDGAME;
+ return Value((r / GrainSize) * GrainSize); // Sign independent
}
// apply_weight() weights score v by score w trying to prevent overflow