X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=d5a4bb970a954e78379c6917f1752bf8eb4bce43;hp=69df7629b881f1ce9e197d4b3b1695a7437379a6;hb=fefb27bab40a1d793fde4f3a0bb7e1e7d66b2fda;hpb=069073ea6882ccb27fe4b571ed08ebe6a4ad8c65 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 69df7629..d5a4bb97 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -27,7 +27,7 @@ #include "material.h" #include "pawns.h" #include "thread.h" -#include "ucioption.h" +#include "uci.h" namespace { @@ -79,13 +79,14 @@ namespace { MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, TOTAL, TERMS_NB }; - Score terms[COLOR_NB][TERMS_NB]; + Score scores[COLOR_NB][TERMS_NB]; EvalInfo ei; ScaleFactor sf; double to_cp(Value v); - void add_term(int idx, Score term_w, Score term_b = SCORE_ZERO); - void format_row(std::stringstream& ss, const char* name, int idx); + void write(int idx, Color c, Score s); + void write(int idx, Score w, Score b = SCORE_ZERO); + void print(std::stringstream& ss, const char* name, int idx); std::string do_trace(const Position& pos); } @@ -140,8 +141,8 @@ namespace { // Threat[attacking][attacked] contains bonuses according to which piece // type attacks which one. const Score Threat[][PIECE_TYPE_NB] = { - { 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 + { S(0, 0), S(0, 38), S(32, 45), S(32, 45), S(41,100), S(35,104) }, // Minor + { S(0, 0), S(7, 28), S(20, 49), S(20, 49), S(8 , 42), S(23, 44) } // Major }; // ThreatenedByPawn[PieceType] contains a penalty according to which piece @@ -370,7 +371,7 @@ namespace { } if (Trace) - Tracing::terms[Us][Pt] = score; + Tracing::write(Pt, Us, score); return score - evaluate_pieces(pos, ei, mobility, mobilityArea); } @@ -484,12 +485,29 @@ namespace { } if (Trace) - Tracing::terms[Us][KING] = score; + Tracing::write(KING, Us, score); return score; } + // max_piece_type() is a helper function used by evaluate_threats() to get + // the value of the biggest PieceType of color C in 'target' bitboard. + + template + inline PieceType max_piece_type(const Position& pos, const Bitboard target) { + + assert(target & (pos.pieces(C) ^ pos.pieces(C, KING))); + + PieceType pt; + for (pt = QUEEN; pt >= KNIGHT; --pt) + if (target & pos.pieces(C, pt)) + break; + + return pt; + } + + // evaluate_threats() assigns bonuses according to the type of attacking piece // and the type of attacked one. @@ -498,33 +516,34 @@ namespace { const Color Them = (Us == WHITE ? BLACK : WHITE); + enum { Minor, Major }; + Bitboard b, weakEnemies, protectedEnemies; Score score = SCORE_ZERO; - enum { Minor, Major }; - // Protected enemies - protectedEnemies = (pos.pieces(Them) ^ pos.pieces(Them,PAWN)) - & ei.attackedBy[Them][PAWN] + // Enemies defended by a pawn and under our attack by a minor piece + protectedEnemies = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) + & ei.attackedBy[Them][PAWN] & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]); if (protectedEnemies) - score += Threat[Minor][type_of(pos.piece_on(lsb(protectedEnemies)))]; + score += Threat[Minor][max_piece_type(pos, protectedEnemies)]; // Enemies not defended by a pawn and under our attack - weakEnemies = pos.pieces(Them) + weakEnemies = pos.pieces(Them) & ~ei.attackedBy[Them][PAWN] - & ei.attackedBy[Us][ALL_PIECES]; + & 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[Minor][type_of(pos.piece_on(lsb(b)))]; + score += Threat[Minor][max_piece_type(pos, b)]; b = weakEnemies & (ei.attackedBy[Us][ROOK] | ei.attackedBy[Us][QUEEN]); if (b) - score += Threat[Major][type_of(pos.piece_on(lsb(b)))]; + score += Threat[Major][max_piece_type(pos, b)]; b = weakEnemies & ~ei.attackedBy[Them][ALL_PIECES]; if (b) @@ -536,7 +555,7 @@ namespace { } if (Trace) - Tracing::terms[Us][Tracing::THREAT] = score; + Tracing::write(Tracing::THREAT, Us, score); return score; } @@ -619,7 +638,7 @@ namespace { } if (Trace) - Tracing::terms[Us][Tracing::PASSED] = apply_weight(score, Weights[PassedPawns]); + Tracing::write(Tracing::PASSED, Us, apply_weight(score, Weights[PassedPawns])); // Add the scores to the middlegame and endgame eval return apply_weight(score, Weights[PassedPawns]); @@ -693,7 +712,7 @@ namespace { // If we have a specialized evaluation function for the current material // configuration, call it and return. if (ei.mi->specialized_eval_exists()) - return ei.mi->evaluate(pos); + return ei.mi->evaluate(pos) + Eval::Tempo; // Probe the pawn hash table ei.pi = Pawns::probe(pos, thisThread->pawnsTable); @@ -780,20 +799,20 @@ namespace { // In case of tracing add all single evaluation contributions for both white and black if (Trace) { - Tracing::add_term(Tracing::MATERIAL, pos.psq_score()); - Tracing::add_term(Tracing::IMBALANCE, ei.mi->material_value()); - Tracing::add_term(PAWN, ei.pi->pawns_value()); - Tracing::add_term(Tracing::MOBILITY, apply_weight(mobility[WHITE], Weights[Mobility]) - , apply_weight(mobility[BLACK], Weights[Mobility])); + Tracing::write(Tracing::MATERIAL, pos.psq_score()); + Tracing::write(Tracing::IMBALANCE, ei.mi->material_value()); + Tracing::write(PAWN, ei.pi->pawns_value()); + Tracing::write(Tracing::MOBILITY, apply_weight(mobility[WHITE], Weights[Mobility]) + , apply_weight(mobility[BLACK], Weights[Mobility])); Score w = ei.mi->space_weight() * evaluate_space(pos, ei); Score b = ei.mi->space_weight() * evaluate_space(pos, ei); - Tracing::add_term(Tracing::SPACE, apply_weight(w, Weights[Space]), apply_weight(b, Weights[Space])); - Tracing::add_term(Tracing::TOTAL, score); + Tracing::write(Tracing::SPACE, apply_weight(w, Weights[Space]), apply_weight(b, Weights[Space])); + Tracing::write(Tracing::TOTAL, score); Tracing::ei = ei; Tracing::sf = sf; } - return pos.side_to_move() == WHITE ? v : -v; + return (pos.side_to_move() == WHITE ? v : -v) + Eval::Tempo; } @@ -801,16 +820,18 @@ namespace { double Tracing::to_cp(Value v) { return double(v) / PawnValueEg; } - void Tracing::add_term(int idx, Score wScore, Score bScore) { + void Tracing::write(int idx, Color c, Score s) { scores[c][idx] = s; } + + void Tracing::write(int idx, Score w, Score b) { - terms[WHITE][idx] = wScore; - terms[BLACK][idx] = bScore; + write(idx, WHITE, w); + write(idx, BLACK, b); } - void Tracing::format_row(std::stringstream& ss, const char* name, int idx) { + void Tracing::print(std::stringstream& ss, const char* name, int idx) { - Score wScore = terms[WHITE][idx]; - Score bScore = terms[BLACK][idx]; + Score wScore = scores[WHITE][idx]; + Score bScore = scores[BLACK][idx]; switch (idx) { case MATERIAL: case IMBALANCE: case PAWN: case TOTAL: @@ -831,7 +852,7 @@ namespace { std::string Tracing::do_trace(const Position& pos) { - std::memset(terms, 0, sizeof(terms)); + std::memset(scores, 0, sizeof(scores)); Value v = do_evaluate(pos); v = pos.side_to_move() == WHITE ? v : -v; // White's point of view @@ -842,21 +863,21 @@ namespace { << " | MG EG | MG EG | MG EG \n" << "----------------+-------------+-------------+-------------\n"; - format_row(ss, "Material", MATERIAL); - format_row(ss, "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); + print(ss, "Material", MATERIAL); + print(ss, "Imbalance", IMBALANCE); + print(ss, "Pawns", PAWN); + print(ss, "Knights", KNIGHT); + print(ss, "Bishops", BISHOP); + print(ss, "Rooks", ROOK); + print(ss, "Queens", QUEEN); + print(ss, "Mobility", MOBILITY); + print(ss, "King safety", KING); + print(ss, "Threats", THREAT); + print(ss, "Passed pawns", PASSED); + print(ss, "Space", SPACE); ss << "----------------+-------------+-------------+-------------\n"; - format_row(ss, "Total", TOTAL); + print(ss, "Total", TOTAL); ss << "\nTotal Evaluation: " << to_cp(v) << " (white side)\n"; @@ -872,7 +893,7 @@ namespace Eval { /// of the position always from the point of view of the side to move. Value evaluate(const Position& pos) { - return do_evaluate(pos) + Tempo; + return do_evaluate(pos); }