X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=49dc07fe671ef0885ca9b5fbfd29a8fd2cc885ad;hp=c7549ce29237d41f8586cf9dab8a03fccbdb435e;hb=bff65a211fcd626c170831878c90a3b440861e2a;hpb=6b909b2343190f2989d21c8f69f40e9f09c530c0 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index c7549ce2..49dc07fe 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,33 +50,33 @@ 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 const int GrainSize = 8; // Evaluation weights, initialized from UCI options - enum { Mobility, PassedPawns, Space, KingDangerUs, KingDangerThem }; - Score Weights[6]; + enum { Mobility, PassedPawns, Space }; + Score Weights[3]; typedef Value V; #define S(mg, eg) make_score(mg, eg) @@ -88,7 +88,7 @@ namespace { // // Values modified by Joona Kiiski const Score WeightsInternal[] = { - S(252, 344), S(216, 266), S(46, 0), S(247, 0), S(259, 0) + S(252, 344), S(216, 266), S(46, 0) }; // MobilityBonus[PieceType][attacked] contains mobility bonuses for middle and @@ -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 @@ -195,6 +195,10 @@ namespace { // the strength of the enemy attack are added up into an integer, which // is used as an index to KingDangerTable[]. // + // King safety evaluation is asymmetrical and different for us (root color) + // and for our opponent. These values are used to init KingDangerTable. + const int KingDangerWeights[] = { 259, 247 }; + // KingAttackWeights[PieceType] contains king attack weights by piece type const int KingAttackWeights[] = { 0, 0, 2, 2, 3, 5 }; @@ -221,11 +225,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 { @@ -281,19 +285,16 @@ namespace Eval { 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. + 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]); + + int KingDanger[] = { KingDangerWeights[0], KingDangerWeights[1] }; + + // If running in analysis mode, make sure we use symmetrical king safety. + // We do so by replacing both KingDanger weights by their average. if (Options["UCI_AnalyseMode"]) - Weights[KingDangerUs] = Weights[KingDangerThem] = (Weights[KingDangerUs] + Weights[KingDangerThem]) / 2; + KingDanger[0] = KingDanger[1] = (KingDanger[0] + KingDanger[1]) / 2; const int MaxSlope = 30; const int Peak = 1280; @@ -302,8 +303,8 @@ namespace Eval { { 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]); + KingDangerTable[0][i] = apply_weight(make_score(t, 0), make_score(KingDanger[0], 0)); + KingDangerTable[1][i] = apply_weight(make_score(t, 0), make_score(KingDanger[1], 0)); } } @@ -361,11 +362,12 @@ namespace { template Value do_evaluate(const Position& pos, Value& margin) { - assert(!pos.in_check()); + assert(!pos.checkers()); EvalInfo ei; - Value margins[2]; + Value margins[COLOR_NB]; Score score, mobilityWhite, mobilityBlack; + Thread* th = pos.this_thread(); // margins[] store the uncertainty estimation of position's evaluation // that typically is used by the search for pruning decisions. @@ -377,7 +379,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 @@ -389,7 +391,7 @@ Value do_evaluate(const Position& pos, Value& margin) { } // 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 @@ -998,7 +1000,7 @@ Value do_evaluate(const Position& pos, Value& margin) { // Opponent king cannot block because path is defended and position // is not in check. So only friendly pieces can be blockers. - assert(!pos.in_check()); + assert(!pos.checkers()); assert((queeningPath & pos.pieces()) == (queeningPath & pos.pieces(c))); // Add moves needed to free the path from friendly pieces and retest condition @@ -1145,7 +1147,11 @@ Value do_evaluate(const Position& pos, Value& margin) { behind |= (Us == WHITE ? behind >> 8 : behind << 8); behind |= (Us == WHITE ? behind >> 16 : behind << 16); - return popcount(safe) + popcount(behind & safe); + // Since SpaceMask[Us] is fully on our half of the board + assert(unsigned(safe >> (Us == WHITE ? 32 : 0)) == 0); + + // Count safe + (behind & safe) with a single popcount + return popcount((Us == WHITE ? safe << 32 : safe >> 32) | (behind & safe)); }