- const Score TrappedBishopA1H1Penalty = make_score(100, 100);
-
- // Penalty for an undefended bishop or knight
- const Score UndefendedMinorPenalty = make_score(25, 10);
-
- // The SpaceMask[Color] contains the area of the board which is considered
- // by the space evaluation. In the middle game, 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[] = {
- (1ULL << SQ_C2) | (1ULL << SQ_D2) | (1ULL << SQ_E2) | (1ULL << SQ_F2) |
- (1ULL << SQ_C3) | (1ULL << SQ_D3) | (1ULL << SQ_E3) | (1ULL << SQ_F3) |
- (1ULL << SQ_C4) | (1ULL << SQ_D4) | (1ULL << SQ_E4) | (1ULL << SQ_F4),
- (1ULL << SQ_C7) | (1ULL << SQ_D7) | (1ULL << SQ_E7) | (1ULL << SQ_F7) |
- (1ULL << SQ_C6) | (1ULL << SQ_D6) | (1ULL << SQ_E6) | (1ULL << SQ_F6) |
- (1ULL << SQ_C5) | (1ULL << SQ_D5) | (1ULL << SQ_E5) | (1ULL << SQ_F5)
- };
-
- // King danger constants and variables. The king danger scores are taken
- // from the KingDangerTable[]. Various little "meta-bonuses" measuring
- // the strength of the enemy attack are added up into an integer, which
- // is used as an index to KingDangerTable[].
- //
- // KingAttackWeights[PieceType] contains king attack weights by piece type
- const int KingAttackWeights[] = { 0, 0, 2, 2, 3, 5 };
-
- // Bonuses for enemy's safe checks
- const int QueenContactCheckBonus = 6;
- const int RookContactCheckBonus = 4;
- const int QueenCheckBonus = 3;
- const int RookCheckBonus = 2;
- const int BishopCheckBonus = 1;
- const int KnightCheckBonus = 1;
-
- // InitKingDanger[Square] contains penalties based on the position of the
- // defending king, indexed by king's square (from white's point of view).
- const int InitKingDanger[] = {
- 2, 0, 2, 5, 5, 2, 0, 2,
- 2, 2, 4, 8, 8, 4, 2, 2,
- 7, 10, 12, 12, 12, 12, 10, 7,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15,
- 15, 15, 15, 15, 15, 15, 15, 15
- };
-
- // KingDangerTable[Color][attackUnits] contains the actual king danger
- // weighted scores, indexed by color and by a calculated integer number.
- Score KingDangerTable[2][128];
-
- // TracedTerms[Color][PieceType || TracedType] contains a breakdown of the
- // evaluation terms, used when tracing.
- Score TracedScores[2][16];
- std::stringstream TraceStream;
-
- enum TracedType {
- PST = 8, IMBALANCE = 9, MOBILITY = 10, THREAT = 11,
- PASSED = 12, UNSTOPPABLE = 13, SPACE = 14, TOTAL = 15
- };
-
- // Function prototypes
- template<bool Trace>
- Value do_evaluate(const Position& pos, Value& margin);
-
- template<Color Us>
- void init_eval_info(const Position& pos, EvalInfo& ei);
-
- template<Color Us, bool Trace>
- 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[]);
-
- template<Color Us>
- Score evaluate_threats(const Position& pos, EvalInfo& ei);
-
- template<Color Us>
- int evaluate_space(const Position& pos, EvalInfo& ei);
-
- template<Color Us>
- Score evaluate_passed_pawns(const Position& pos, EvalInfo& ei);
-
- Score evaluate_unstoppable_pawns(const Position& pos, EvalInfo& ei);
-
- Value interpolate(const Score& v, Phase ph, ScaleFactor sf);
- Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight);
- double to_cp(Value v);
- void trace_add(int idx, Score term_w, Score term_b = SCORE_ZERO);
- void trace_row(const char* name, int idx);
-}
-
-
-namespace Eval {
-
- Color RootColor;
-
- /// evaluate() is the main evaluation function. It always computes two
- /// values, an endgame score and a middle game score, and interpolates
- /// between them based on the remaining material.
-
- Value evaluate(const Position& pos, Value& margin) {
- return do_evaluate<false>(pos, margin);
- }
-
-
- /// init() computes evaluation weights from the corresponding UCI parameters
- /// and setup king tables.
-
- void init() {
-
- Weights[Mobility] = weight_option("Mobility (Middle Game)", "Mobility (Endgame)", WeightsInternal[Mobility]);
- Weights[PassedPawns] = weight_option("Passed Pawns (Middle Game)", "Passed Pawns (Endgame)", WeightsInternal[PassedPawns]);
- Weights[Space] = weight_option("Space", "Space", WeightsInternal[Space]);
- Weights[KingDangerUs] = weight_option("Cowardice", "Cowardice", WeightsInternal[KingDangerUs]);
- Weights[KingDangerThem] = weight_option("Aggressiveness", "Aggressiveness", WeightsInternal[KingDangerThem]);
-
- // King safety is asymmetrical. Our king danger level is weighted by
- // "Cowardice" UCI parameter, instead the opponent one by "Aggressiveness".
- // If running in analysis mode, make sure we use symmetrical king safety. We
- // do this by replacing both Weights[kingDangerUs] and Weights[kingDangerThem]
- // by their average.
- if (Options["UCI_AnalyseMode"])
- Weights[KingDangerUs] = Weights[KingDangerThem] = (Weights[KingDangerUs] + Weights[KingDangerThem]) / 2;
-
- const int MaxSlope = 30;
- const int Peak = 1280;
-
- for (int t = 0, i = 1; i < 100; i++)
- {
- t = std::min(Peak, std::min(int(0.4 * i * i), t + MaxSlope));
-
- KingDangerTable[1][i] = apply_weight(make_score(t, 0), Weights[KingDangerUs]);
- KingDangerTable[0][i] = apply_weight(make_score(t, 0), Weights[KingDangerThem]);
- }
- }
-
-
- /// trace() is like evaluate() but instead of a value returns a string suitable
- /// to be print on stdout with the detailed descriptions and values of each
- /// evaluation term. Used mainly for debugging.
-
- std::string trace(const Position& pos) {
-
- Value margin;
- std::string totals;
-
- RootColor = pos.side_to_move();
-
- TraceStream.str("");
- TraceStream << std::showpoint << std::showpos << std::fixed << std::setprecision(2);
- memset(TracedScores, 0, 2 * 16 * sizeof(Score));