- {}, {},
- { S(-35,-30), S(-22,-20), S(-9,-10), S( 3, 0), S(15, 10), S(27, 20), // Knights
- S( 37, 28), S( 42, 31), S(44, 33) },
- { S(-22,-27), S( -8,-13), S( 6, 1), S(20, 15), S(34, 29), S(48, 43), // Bishops
- S( 60, 55), S( 68, 63), S(74, 68), S(77, 72), S(80, 75), S(82, 77),
- S( 84, 79), S( 86, 81) },
- { S(-17,-33), S(-11,-16), S(-5, 0), S( 1, 16), S( 7, 32), S(13, 48), // Rooks
- S( 18, 64), S( 22, 80), S(26, 96), S(29,109), S(31,115), S(33,119),
- S( 35,122), S( 36,123), S(37,124) },
- { S(-12,-20), S( -8,-13), S(-5, -7), S(-2, -1), S( 1, 5), S( 4, 11), // Queens
- S( 7, 17), S( 10, 23), S(13, 29), S(16, 34), S(18, 38), S(20, 40),
- S( 22, 41), S( 23, 41), S(24, 41), S(25, 41), S(25, 41), S(25, 41),
- S( 25, 41), S( 25, 41), S(25, 41), S(25, 41), S(25, 41), S(25, 41),
- S( 25, 41), S( 25, 41), S(25, 41), S(25, 41) }
+ {}, {},
+ { S(-35,-30), S(-22,-20), S(-9,-10), S( 3, 0), S(15, 10), S(27, 20), // Knights
+ S( 37, 28), S( 42, 31), S(44, 33) },
+ { S(-22,-27), S( -8,-13), S( 6, 1), S(20, 15), S(34, 29), S(48, 43), // Bishops
+ S( 60, 55), S( 68, 63), S(74, 68), S(77, 72), S(80, 75), S(82, 77),
+ S( 84, 79), S( 86, 81) },
+ { S(-17,-33), S(-11,-16), S(-5, 0), S( 1, 16), S( 7, 32), S(13, 48), // Rooks
+ S( 18, 64), S( 22, 80), S(26, 96), S(29,109), S(31,115), S(33,119),
+ S( 35,122), S( 36,123), S(37,124) },
+ { S(-12,-20), S( -8,-13), S(-5, -7), S(-2, -1), S( 1, 5), S( 4, 11), // Queens
+ S( 7, 17), S( 10, 23), S(13, 29), S(16, 34), S(18, 38), S(20, 40),
+ S( 22, 41), S( 23, 41), S(24, 41), S(25, 41), S(25, 41), S(25, 41),
+ S( 25, 41), S( 25, 41), S(25, 41), S(25, 41), S(25, 41), S(25, 41),
+ S( 25, 41), S( 25, 41), S(25, 41), S(25, 41) }
V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // Knights
V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0),
V(0), V(0), V(4), V(8), V(8), V(4), V(0), V(0),
V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // Knights
V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0),
V(0), V(0), V(4), V(8), V(8), V(4), V(0), V(0),
- {}, {},
- { S(0, 0), S( 7, 39), S( 0, 0), S(24, 49), S(41,100), S(41,100) }, // KNIGHT
- { S(0, 0), S( 7, 39), S(24, 49), S( 0, 0), S(41,100), S(41,100) }, // BISHOP
- { S(0, 0), S( 0, 22), S(15, 49), S(15, 49), S( 0, 0), S(24, 49) }, // ROOK
- { S(0, 0), S(15, 39), S(15, 39), S(15, 39), S(15, 39), S( 0, 0) } // QUEEN
+ { S(0, 0), S( 7, 39), S(24, 49), S(24, 49), S(41,100), S(41,100) }, // Minor
+ { S(0, 0), S(15, 39), S(15, 45), S(15, 45), S(15, 45), S(24, 49) } // Major
- const int QueenContactCheck = 6;
- const int RookContactCheck = 4;
- const int QueenCheck = 3;
- const int RookCheck = 2;
- const int BishopCheck = 1;
- const int KnightCheck = 1;
-
- // KingExposed[Square] contains penalties based on the position of the
- // defending king, indexed by king's square (from white's point of view).
- const int KingExposed[] = {
- 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
- };
+ const int QueenContactCheck = 24;
+ const int RookContactCheck = 16;
+ const int QueenCheck = 12;
+ const int RookCheck = 8;
+ const int BishopCheck = 2;
+ const int KnightCheck = 3;
- // evaluate_threats<>() assigns bonuses according to the type of attacking piece
- // and the type of attacked one.
-
- template<Color Us, bool Trace>
- Score evaluate_threats(const Position& pos, const EvalInfo& ei) {
-
- const Color Them = (Us == WHITE ? BLACK : WHITE);
-
- Bitboard b, undefendedMinors, weakEnemies;
- Score score = SCORE_ZERO;
-
- // Undefended minors get penalized even if not under attack
- undefendedMinors = pos.pieces(Them, BISHOP, KNIGHT)
- & ~ei.attackedBy[Them][ALL_PIECES];
-
- if (undefendedMinors)
- score += UndefendedMinor;
-
- // Enemy pieces not defended by a pawn and under our attack
- weakEnemies = pos.pieces(Them)
- & ~ei.attackedBy[Them][PAWN]
- & ei.attackedBy[Us][ALL_PIECES];
-
- // Add bonus according to type of attacked enemy piece and to the
- // type of attacking piece, from knights to queens. Kings are not
- // considered because are already handled in king evaluation.
- if (weakEnemies)
- for (PieceType pt1 = KNIGHT; pt1 < KING; ++pt1)
- {
- b = ei.attackedBy[Us][pt1] & weakEnemies;
- if (b)
- for (PieceType pt2 = PAWN; pt2 < KING; ++pt2)
- if (b & pos.pieces(pt2))
- score += Threat[pt1][pt2];
- }
-
- if (Trace)
- Tracing::scores[Us][THREAT] = score;
-
- return score;
- }
-
-
- // evaluate_pieces_of_color<>() assigns bonuses and penalties to all the
+ // evaluate_pieces() assigns bonuses and penalties to all the
- score += evaluate_pieces<KNIGHT, Us, Trace>(pos, ei, mobility, mobilityArea);
- score += evaluate_pieces<BISHOP, Us, Trace>(pos, ei, mobility, mobilityArea);
- score += evaluate_pieces<ROOK, Us, Trace>(pos, ei, mobility, mobilityArea);
- score += evaluate_pieces<QUEEN, Us, Trace>(pos, ei, mobility, mobilityArea);
+ Score score = evaluate_pieces<KNIGHT, Us, Trace>(pos, ei, mobility, mobilityArea)
+ + evaluate_pieces<BISHOP, Us, Trace>(pos, ei, mobility, mobilityArea)
+ + evaluate_pieces<ROOK, Us, Trace>(pos, ei, mobility, mobilityArea)
+ + evaluate_pieces<QUEEN, Us, Trace>(pos, ei, mobility, mobilityArea);
- // evaluate_passed_pawns<>() evaluates the passed pawns of the given color
+ // evaluate_threats() assigns bonuses according to the type of attacking piece
+ // and the type of attacked one.
+
+ template<Color Us, bool Trace>
+ Score evaluate_threats(const Position& pos, const EvalInfo& ei) {
+
+ const Color Them = (Us == WHITE ? BLACK : WHITE);
+
+ Bitboard b, undefendedMinors, weakEnemies;
+ Score score = SCORE_ZERO;
+
+ // Undefended minors get penalized even if they are not under attack
+ undefendedMinors = pos.pieces(Them, BISHOP, KNIGHT)
+ & ~ei.attackedBy[Them][ALL_PIECES];
+
+ if (undefendedMinors)
+ score += UndefendedMinor;
+
+ // Enemy pieces not defended by a pawn and under our attack
+ weakEnemies = pos.pieces(Them)
+ & ~ei.attackedBy[Them][PAWN]
+ & ei.attackedBy[Us][ALL_PIECES];
+
+ // Add a bonus according if the attacking pieces are minor or major
+ if (weakEnemies)
+ {
+ b = weakEnemies & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]);
+ if (b)
+ score += Threat[0][type_of(pos.piece_on(lsb(b)))];
+
+ b = weakEnemies & (ei.attackedBy[Us][ROOK] | ei.attackedBy[Us][QUEEN]);
+ if (b)
+ score += Threat[1][type_of(pos.piece_on(lsb(b)))];
+ }
+
+ if (Trace)
+ Tracing::terms[Us][Tracing::THREAT] = score;
+
+ return score;
+ }
+
+
+ // evaluate_passed_pawns() evaluates the passed pawns of the given color
- stream.str("");
- stream << std::showpoint << std::showpos << std::fixed << std::setprecision(2);
- std::memset(scores, 0, 2 * (TOTAL + 1) * sizeof(Score));
-
- Value margin;
- do_evaluate<true>(pos, margin);
-
- std::string totals = stream.str();
- stream.str("");
-
- stream << std::setw(21) << "Eval term " << "| White | Black | Total \n"
- << " | MG EG | MG EG | MG EG \n"
- << "---------------------+-------------+-------------+---------------\n";
-
- row("Material, PST, Tempo", PST);
- row("Material imbalance", IMBALANCE);
- row("Pawns", PAWN);
- row("Knights", KNIGHT);
- row("Bishops", BISHOP);
- row("Rooks", ROOK);
- row("Queens", QUEEN);
- row("Mobility", MOBILITY);
- row("King safety", KING);
- row("Threats", THREAT);
- row("Passed pawns", PASSED);
- row("Space", SPACE);
-
- stream << "---------------------+-------------+-------------+---------------\n";
- row("Total", TOTAL);
- stream << totals;
-
- return stream.str();
+ std::memset(terms, 0, sizeof(terms));
+
+ Value v = do_evaluate<true>(pos);
+
+ std::stringstream ss;
+ ss << std::showpoint << std::showpos << std::fixed << std::setprecision(2)
+ << " Eval term | White | Black | Total \n"
+ << " | MG EG | MG EG | MG EG \n"
+ << "---------------------+-------------+-------------+---------------\n";
+
+ format_row(ss, "Material, PST, Tempo", PST);
+ format_row(ss, "Material imbalance", IMBALANCE);
+ format_row(ss, "Pawns", PAWN);
+ format_row(ss, "Knights", KNIGHT);
+ format_row(ss, "Bishops", BISHOP);
+ format_row(ss, "Rooks", ROOK);
+ format_row(ss, "Queens", QUEEN);
+ format_row(ss, "Mobility", MOBILITY);
+ format_row(ss, "King safety", KING);
+ format_row(ss, "Threats", THREAT);
+ format_row(ss, "Passed pawns", PASSED);
+ format_row(ss, "Space", SPACE);
+
+ ss << "---------------------+-------------+-------------+---------------\n";
+ format_row(ss, "Total", TOTAL);
+
+ ss << "\nScaling: " << std::noshowpos
+ << std::setw(6) << 100.0 * ei.mi->game_phase() / 128.0 << "% MG, "
+ << std::setw(6) << 100.0 * (1.0 - ei.mi->game_phase() / 128.0) << "% * "
+ << std::setw(6) << (100.0 * sf) / SCALE_FACTOR_NORMAL << "% EG.\n"
+ << "Total evaluation: " << to_cp(v);
+
+ return ss.str();