X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=da4860fe1ce25b26ae89d44fa97b6392a4ae23ba;hp=55c5014a447c7f44c6614815bf49a100e4b4a87d;hb=c7a932bc744f899f53ce0013cbbbaa86915bb2e8;hpb=6125966da02eab5b726802286ef111c4adc63eab diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 55c5014a..da4860fe 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -23,7 +23,6 @@ //// #include -#include #include "bitcount.h" #include "evaluate.h" @@ -61,8 +60,9 @@ namespace { S(248, 271), S(233, 201), S(252, 259), S(46, 0), S(247, 0), S(259, 0) }; - // Pieces mobility bonus in middle game and endgame, indexed by piece type - // and number of attacked squares not occupied by friendly pieces. + // MobilityBonus[PieceType][attacked] contains mobility bonuses for middle and + // end game, indexed by piece type and number of attacked squares not occupied + // by friendly pieces. const Score MobilityBonus[][32] = { {}, {}, { S(-38,-33), S(-25,-23), S(-12,-13), S( 0, -3), S(12, 7), S(25, 17), // Knights @@ -81,8 +81,8 @@ namespace { S( 20, 35), S( 20, 35) } }; - // Outpost bonuses for knights and bishops, indexed by square (from white's - // point of view). + // 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] = { { // A B C D E F G H @@ -105,9 +105,9 @@ namespace { V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) } }; - // ThreatBonus[attacking][attacked] contains bonus according to which - // piece type attacks which one. - const Score ThreatBonus[8][8] = { + // ThreatBonus[attacking][attacked] contains threat bonuses according to + // which piece type attacks which one. + const Score ThreatBonus[][8] = { {}, {}, { 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 @@ -115,9 +115,9 @@ namespace { { S(0, 0), S(15, 39), S(15, 39), S(15, 39), S(15, 39), S( 0, 0) } // QUEEN }; - // ThreatedByPawnPenalty[] contains a penalty according to which piece - // type is attacked by an enemy pawn. - const Score ThreatedByPawnPenalty[8] = { + // ThreatedByPawnPenalty[PieceType] contains a penalty according to which + // piece type is attacked by an enemy pawn. + const Score ThreatedByPawnPenalty[] = { S(0, 0), S(0, 0), S(56, 70), S(56, 70), S(76, 99), S(86, 118) }; @@ -135,26 +135,26 @@ namespace { // right to castle. const Value TrappedRookPenalty = Value(180); - // The SpaceMask[color] contains the area of the board which is considered + // 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[2] = { - (1ULL< - void evaluate_pieces_of_color(const Position& pos, EvalInfo& ei); + Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei); template void evaluate_king(const Position& pos, EvalInfo& ei); @@ -240,15 +241,14 @@ template Value do_evaluate(const Position& pos, EvalInfo& ei) { ScaleFactor factor[2]; + Score mobility; assert(pos.is_ok()); assert(pos.thread() >= 0 && pos.thread() < MAX_THREADS); assert(!pos.is_check()); - memset(&ei, 0, sizeof(EvalInfo)); - // Initialize by reading the incrementally updated scores included in the - // position object (material + piece square tables) + // position object (material + piece square tables). ei.value = pos.value(); // Probe the material hash table @@ -256,7 +256,7 @@ Value do_evaluate(const Position& pos, EvalInfo& ei) { ei.value += ei.mi->material_value(); // If we have a specialized evaluation function for the current material - // configuration, call it and return + // configuration, call it and return. if (ei.mi->specialized_eval_exists()) return ei.mi->evaluate(pos); @@ -272,9 +272,10 @@ Value do_evaluate(const Position& pos, EvalInfo& ei) { init_attack_tables(pos, ei); init_attack_tables(pos, ei); - // Evaluate pieces - evaluate_pieces_of_color(pos, ei); - evaluate_pieces_of_color(pos, ei); + // Evaluate pieces and mobility + mobility = evaluate_pieces_of_color(pos, ei) + - evaluate_pieces_of_color(pos, ei); + ei.value += apply_weight(mobility, Weights[Mobility]); // Kings. Kings are evaluated after all other pieces for both sides, // because we need complete attack information for all pieces when computing @@ -314,9 +315,6 @@ Value do_evaluate(const Position& pos, EvalInfo& ei) { } } - // Mobility - ei.value += apply_weight(ei.mobility, Weights[Mobility]); - // If we don't already have an unusual scale factor, check for opposite // colored bishop endgames, and use a lower scale for those if ( phase < PHASE_MIDGAME @@ -429,8 +427,8 @@ namespace { ei.kingZone[Us] = (b | (Us == WHITE ? b >> 8 : b << 8)); ei.attackedBy[Us][PAWN] = ei.pi->pawn_attacks(Us); b &= ei.attackedBy[Us][PAWN]; - if (b) - ei.kingAttackersCount[Us] = count_1s_max_15(b) / 2; + ei.kingAttackersCount[Us] = b ? count_1s_max_15(b) / 2 : 0; + ei.kingAdjacentZoneAttacksCount[Us] = ei.kingAttackersWeight[Us] = 0; } @@ -463,16 +461,19 @@ namespace { // evaluate_pieces<>() assigns bonuses and penalties to the pieces of a given color template - void evaluate_pieces(const Position& pos, EvalInfo& ei, Bitboard no_mob_area) { + Score evaluate_pieces(const Position& pos, EvalInfo& ei, Bitboard no_mob_area) { Bitboard b; Square s, ksq; int mob; File f; + Score mobility = SCORE_ZERO; const Color Them = (Us == WHITE ? BLACK : WHITE); const Square* ptr = pos.piece_list_begin(Us, Piece); + ei.attackedBy[Us][Piece] = 0; + while ((s = *ptr++) != SQ_NONE) { // Find attacked squares, including x-ray attacks for bishops and rooks @@ -502,7 +503,7 @@ namespace { mob = (Piece != QUEEN ? count_1s_max_15(b & no_mob_area) : count_1s(b & no_mob_area)); - ei.mobility += Sign[Us] * MobilityBonus[Piece][mob]; + mobility += MobilityBonus[Piece][mob]; // Decrease score if we are attacked by an enemy pawn. Remaining part // of threat evaluation must be done later when we have full attack info. @@ -561,6 +562,7 @@ namespace { } } } + return mobility; } @@ -601,22 +603,25 @@ namespace { // pieces of a given color. template - void evaluate_pieces_of_color(const Position& pos, EvalInfo& ei) { + Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei) { const Color Them = (Us == WHITE ? BLACK : WHITE); + Score mobility = SCORE_ZERO; + // Do not include in mobility squares protected by enemy pawns or occupied by our pieces const Bitboard no_mob_area = ~(ei.attackedBy[Them][PAWN] | pos.pieces_of_color(Us)); - evaluate_pieces(pos, ei, no_mob_area); - evaluate_pieces(pos, ei, no_mob_area); - evaluate_pieces(pos, ei, no_mob_area); - evaluate_pieces(pos, ei, no_mob_area); + mobility += evaluate_pieces(pos, ei, no_mob_area); + mobility += evaluate_pieces(pos, ei, no_mob_area); + mobility += evaluate_pieces(pos, ei, no_mob_area); + mobility += evaluate_pieces(pos, ei, no_mob_area); // Sum up all attacked squares ei.attackedBy[Us][0] = ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK] | ei.attackedBy[Us][QUEEN] | ei.attackedBy[Us][KING]; + return mobility; } @@ -704,13 +709,14 @@ namespace { attackUnits = Min(99, Max(0, attackUnits)); // Finally, extract the king danger score from the KingDangerTable[] - // array and subtract the score from evaluation. Set also ei.kingDanger[] + // array and subtract the score from evaluation. Set also ei.margin[] // value that will be used for pruning because this value can sometimes // 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. ei.value -= Sign[Us] * KingDangerTable[Us][attackUnits]; - ei.kingDanger[Us] = mg_value(KingDangerTable[Us][attackUnits]); - } + ei.margin[Us] = mg_value(KingDangerTable[Us][attackUnits]); + } else + ei.margin[Us] = VALUE_ZERO; } @@ -721,11 +727,14 @@ namespace { const Color Them = (Us == WHITE ? BLACK : WHITE); + Score bonus = SCORE_ZERO; Bitboard squaresToQueen, defendedSquares, unsafeSquares, supportingPawns; Bitboard b = ei.pi->passed_pawns(Us); - while (b) - { + if (!b) + return; + + do { Square s = pop_1st_bit(&b); assert(pos.pawn_is_passed(Us, s)); @@ -800,11 +809,12 @@ namespace { else if (pos.pieces(ROOK, QUEEN, Them)) ebonus -= ebonus / 4; } + bonus += make_score(mbonus, ebonus); - // Add the scores for this pawn to the middle game and endgame eval - ei.value += Sign[Us] * apply_weight(make_score(mbonus, ebonus), Weights[PassedPawns]); + } while (b); - } // while + // Add the scores to the middle game and endgame eval + ei.value += Sign[Us] * apply_weight(bonus, Weights[PassedPawns]); }