// Penalties for enemy's safe checks
const int QueenContactCheck = 89;
- const int RookContactCheck = 71;
const int QueenCheck = 50;
- const int RookCheck = 37;
+ const int RookCheck = 45;
const int BishopCheck = 6;
const int KnightCheck = 14;
// number and types of the enemy's attacking pieces, the number of
// attacked and undefended squares around our king and the quality of
// the pawn shelter (current 'score' value).
- attackUnits = std::min(74, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them])
- + 8 * ei.kingAdjacentZoneAttacksCount[Them]
- + 25 * popcount<Max15>(undefended)
+ attackUnits = std::min(72, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them])
+ + 9 * ei.kingAdjacentZoneAttacksCount[Them]
+ + 27 * popcount<Max15>(undefended)
+ 11 * !!ei.pinnedPieces[Us]
- - 60 * !pos.count<QUEEN>(Them)
+ - 64 * !pos.count<QUEEN>(Them)
- mg_value(score) / 8;
// Analyse the enemy's safe queen contact checks. Firstly, find the
attackUnits += QueenContactCheck * popcount<Max15>(b);
}
- // Analyse the enemy's safe rook contact checks. Firstly, find the
- // undefended squares around the king reachable by the enemy rooks...
- b = undefended & ei.attackedBy[Them][ROOK] & ~pos.pieces(Them);
-
- // Consider only squares where the enemy's rook gives check
- b &= PseudoAttacks[ROOK][ksq];
-
- if (b)
- {
- // ...and then remove squares not supported by another enemy piece
- b &= ( ei.attackedBy[Them][PAWN] | ei.attackedBy[Them][KNIGHT]
- | ei.attackedBy[Them][BISHOP]);
-
- if (b)
- attackUnits += RookContactCheck * popcount<Max15>(b);
- }
-
// Analyse the enemy's safe distance checks for sliders and knights
safe = ~(ei.attackedBy[Us][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 ? 15 : !(unsafeSquares & blockSq) ? 9 : 0;
+ int k = !unsafeSquares ? 18 : !(unsafeSquares & blockSq) ? 8 : 0;
// If the path to queen is fully defended, assign a big bonus.
// Otherwise assign a smaller bonus if the block square is defended.
return make_score(bonus * weight * weight, 0);
}
+
+ // evaluate_initiative() computes the initiative correction value for the position, i.e.
+ // second order bonus/malus based on the known attacking/defending status of the players.
+ Score evaluate_initiative(const Position& pos, const EvalInfo& ei, const Score positional_score) {
+
+ int pawns = pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK);
+ int king_separation = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
+ int asymmetry = ei.pi->pawn_asymmetry();
+
+ // Compute the initiative bonus for the attacking side
+ int attacker_bonus = 8 * (pawns + asymmetry + king_separation) - 120;
+
+ // Now apply the bonus: note that we find the attacking side by extracting the sign
+ // of the endgame value of "positional_score", and that we carefully cap the bonus so
+ // that the endgame score with the correction will never be divided by more than two.
+ int eg = eg_value(positional_score);
+ int value = ((eg > 0) - (eg < 0)) * std::max( attacker_bonus , -abs( eg / 2 ) );
+
+ return make_score( 0 , value ) ;
+ }
+
} // namespace
}
// Evaluate space for both sides, only during opening
- if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 11756)
+ 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];
+
+ // Evaluate initiative
+ score += evaluate_initiative(pos, ei, score);
// Scale winning side if position is more drawish than it appears
Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK;
// 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(32) : ScaleFactor(8);
+ 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(50 * sf / SCALE_FACTOR_NORMAL);
+ 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(56) : ScaleFactor(38);
+ sf = ei.pi->pawn_span(strongSide) ? ScaleFactor(51) : ScaleFactor(37);
}
- // Scale endgame by number of pawns
- int p = pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK);
- int v_eg = 1 + abs(int(eg_value(score)));
- sf = ScaleFactor(std::max(sf / 2, sf - 7 * SCALE_FACTOR_NORMAL * (14 - p) / v_eg));
-
// Interpolate between a middlegame and a (scaled by 'sf') endgame score
Value v = mg_value(score) * int(me->game_phase())
+ eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;