X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=8d9d01a71a7eff742bed41cce7bdf28c4d3ed391;hp=c7549ce29237d41f8586cf9dab8a03fccbdb435e;hb=158014b39d69eaaf791d4913b98ffde5c4d7a874;hpb=6b909b2343190f2989d21c8f69f40e9f09c530c0 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index c7549ce2..8d9d01a7 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -36,13 +36,13 @@ namespace { struct EvalInfo { // Pointers to material and pawn hash table entries - MaterialEntry* mi; - PawnEntry* pi; + Material::Entry* mi; + Pawns::Entry* pi; // attackedBy[color][piece type] is a bitboard representing all squares // attacked by a given color and piece type, attackedBy[color][0] contains // all squares attacked by the given color. - Bitboard attackedBy[2][8]; + Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB]; // kingRing[color] is the zone around the king which is considered // by the king safety evaluation. This consists of the squares directly @@ -50,25 +50,25 @@ namespace { // squares two ranks in front of the king. For instance, if black's king // is on g8, kingRing[BLACK] is a bitboard containing the squares f8, h8, // f7, g7, h7, f6, g6 and h6. - Bitboard kingRing[2]; + Bitboard kingRing[COLOR_NB]; // kingAttackersCount[color] is the number of pieces of the given color // which attack a square in the kingRing of the enemy king. - int kingAttackersCount[2]; + int kingAttackersCount[COLOR_NB]; // kingAttackersWeight[color] is the sum of the "weight" of the pieces of the // given color which attack a square in the kingRing of the enemy king. The // weights of the individual piece types are given by the variables // QueenAttackWeight, RookAttackWeight, BishopAttackWeight and // KnightAttackWeight in evaluate.cpp - int kingAttackersWeight[2]; + int kingAttackersWeight[COLOR_NB]; // kingAdjacentZoneAttacksCount[color] is the number of attacks to squares // directly adjacent to the king of the given color. Pieces which attack // more than one square are counted multiple times. For instance, if black's // king is on g8 and there's a white knight on g5, this knight adds // 2 to kingAdjacentZoneAttacksCount[BLACK]. - int kingAdjacentZoneAttacksCount[2]; + int kingAdjacentZoneAttacksCount[COLOR_NB]; }; // Evaluation grain size, must be a power of 2 @@ -114,7 +114,7 @@ namespace { // OutpostBonus[PieceType][Square] contains outpost bonuses of knights and // bishops, indexed by piece type and square (from white's point of view). - const Value OutpostBonus[][64] = { + const Value OutpostBonus[][SQUARE_NB] = { { // A B C D E F G H V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // Knights @@ -134,7 +134,7 @@ namespace { // ThreatBonus[attacking][attacked] contains threat bonuses according to // which piece type attacks which one. - const Score ThreatBonus[][8] = { + const Score ThreatBonus[][PIECE_TYPE_NB] = { {}, {}, { 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 @@ -221,11 +221,11 @@ namespace { // KingDangerTable[Color][attackUnits] contains the actual king danger // weighted scores, indexed by color and by a calculated integer number. - Score KingDangerTable[2][128]; + Score KingDangerTable[COLOR_NB][128]; // TracedTerms[Color][PieceType || TracedType] contains a breakdown of the // evaluation terms, used when tracing. - Score TracedScores[2][16]; + Score TracedScores[COLOR_NB][16]; std::stringstream TraceStream; enum TracedType { @@ -244,7 +244,7 @@ namespace { Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei, Score& mobility); template - Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]); + Score evaluate_king(const Position& pos, EvalInfo& ei, int16_t margins[]); template Score evaluate_threats(const Position& pos, EvalInfo& ei); @@ -364,12 +364,27 @@ Value do_evaluate(const Position& pos, Value& margin) { assert(!pos.in_check()); EvalInfo ei; - Value margins[2]; Score score, mobilityWhite, mobilityBlack; + Key key = pos.key(); + Thread* th = pos.this_thread(); + Eval::Entry* e = th->evalTable[key]; + + // If e->key matches the position's hash key, it means that we have analysed + // this node before, and we can simply return the information we found the last + // time instead of recomputing it. + if (e->key == key) + { + margin = Value(e->margins[pos.side_to_move()]); + return e->value; + } + + // Otherwise we overwrite current content with this node info. + e->key = key; + // margins[] store the uncertainty estimation of position's evaluation // that typically is used by the search for pruning decisions. - margins[WHITE] = margins[BLACK] = VALUE_ZERO; + e->margins[WHITE] = e->margins[BLACK] = VALUE_ZERO; // Initialize score by reading the incrementally updated scores included // in the position object (material + piece square tables) and adding @@ -377,7 +392,7 @@ Value do_evaluate(const Position& pos, Value& margin) { score = pos.psq_score() + (pos.side_to_move() == WHITE ? Tempo : -Tempo); // Probe the material hash table - ei.mi = pos.this_thread()->materialTable.probe(pos); + ei.mi = Material::probe(pos, th->materialTable, th->endgames); score += ei.mi->material_value(); // If we have a specialized evaluation function for the current material @@ -385,11 +400,12 @@ Value do_evaluate(const Position& pos, Value& margin) { if (ei.mi->specialized_eval_exists()) { margin = VALUE_ZERO; - return ei.mi->evaluate(pos); + e->value = ei.mi->evaluate(pos); + return e->value; } // Probe the pawn hash table - ei.pi = pos.this_thread()->pawnTable.probe(pos); + ei.pi = Pawns::probe(pos, th->pawnsTable); score += ei.pi->pawns_value(); // Initialize attack and king safety bitboards @@ -404,8 +420,8 @@ Value do_evaluate(const Position& pos, Value& margin) { // Evaluate kings after all other pieces because we need complete attack // information when computing the king safety evaluation. - score += evaluate_king(pos, ei, margins) - - evaluate_king(pos, ei, margins); + score += evaluate_king(pos, ei, e->margins) + - evaluate_king(pos, ei, e->margins); // Evaluate tactical threats, we need full attack information including king score += evaluate_threats(pos, ei) @@ -451,7 +467,7 @@ Value do_evaluate(const Position& pos, Value& margin) { sf = ScaleFactor(50); } - margin = margins[pos.side_to_move()]; + margin = Value(e->margins[pos.side_to_move()]); Value v = interpolate(score, ei.mi->game_phase(), sf); // In case of tracing add all single evaluation contributions for both white and black @@ -468,8 +484,8 @@ Value do_evaluate(const Position& pos, Value& margin) { Score b = make_score(ei.mi->space_weight() * evaluate_space(pos, ei), 0); trace_add(SPACE, apply_weight(w, Weights[Space]), apply_weight(b, Weights[Space])); trace_add(TOTAL, score); - TraceStream << "\nUncertainty margin: White: " << to_cp(margins[WHITE]) - << ", Black: " << to_cp(margins[BLACK]) + TraceStream << "\nUncertainty margin: White: " << to_cp(Value(e->margins[WHITE])) + << ", Black: " << to_cp(Value(e->margins[BLACK])) << "\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) << "% * " @@ -477,7 +493,7 @@ Value do_evaluate(const Position& pos, Value& margin) { << "Total evaluation: " << to_cp(v); } - return pos.side_to_move() == WHITE ? v : -v; + return e->value = pos.side_to_move() == WHITE ? v : -v; } @@ -752,7 +768,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // evaluate_king<>() assigns bonuses and penalties to a king of a given color template - Score evaluate_king(const Position& pos, EvalInfo& ei, Value margins[]) { + Score evaluate_king(const Position& pos, EvalInfo& ei, int16_t margins[]) { const Color Them = (Us == WHITE ? BLACK : WHITE); @@ -852,7 +868,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // be very big, and so capturing a single attacking piece can therefore // result in a score change far bigger than the value of the captured piece. score -= KingDangerTable[Us == Search::RootColor][attackUnits]; - margins[Us] += mg_value(KingDangerTable[Us == Search::RootColor][attackUnits]); + margins[Us] += int16_t(mg_value(KingDangerTable[Us == Search::RootColor][attackUnits])); } if (Trace)