X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fevaluate.cpp;h=64760d4da5d206f7efc4ac6535fb0b0266cf261a;hp=f6fdb19879dfb9e8fb6da9dae852da250926863e;hb=c0136fb7286416be2ec179b4787f53d77023eeaf;hpb=7f095b0a36cd791e610a9c308b36d845594a78d8 diff --git a/src/evaluate.cpp b/src/evaluate.cpp index f6fdb198..64760d4d 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -134,10 +134,10 @@ namespace { // piece type attacks which one. const Score ThreatBonus[8][8] = { {}, {}, - { S(0, 0), S(18,37), S( 0, 0), S(37,47), S(55,97), S(55,97) }, // KNIGHT - { S(0, 0), S(18,37), S(37,47), S( 0, 0), S(55,97), S(55,97) }, // BISHOP - { S(0, 0), S( 9,27), S(27,47), S(27,47), S( 0, 0), S(37,47) }, // ROOK - { S(0, 0), S(27,37), S(27,37), S(27,37), S(27,37), S( 0, 0) } // QUEEN + { 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(-1, 29), 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 }; // ThreatedByPawnPenalty[] contains a penalty according to which piece @@ -242,6 +242,9 @@ namespace { template Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID); + template + void init_attack_tables(const Position& pos, EvalInfo& ei); + template void evaluate_pieces_of_color(const Position& pos, EvalInfo& ei); @@ -285,7 +288,6 @@ namespace { template Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) { - Bitboard b; ScaleFactor factor[2]; assert(pos.is_ok()); @@ -315,22 +317,9 @@ Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) { ei.pi = PawnTable[threadID]->get_pawn_info(pos); ei.value += apply_weight(ei.pi->pawns_value(), Weights[PawnStructure]); - // Initialize king attack bitboards and king attack zones for both sides - ei.attackedBy[WHITE][KING] = pos.attacks_from(pos.king_square(WHITE)); - ei.attackedBy[BLACK][KING] = pos.attacks_from(pos.king_square(BLACK)); - ei.kingZone[WHITE] = ei.attackedBy[BLACK][KING] | (ei.attackedBy[BLACK][KING] >> 8); - ei.kingZone[BLACK] = ei.attackedBy[WHITE][KING] | (ei.attackedBy[WHITE][KING] << 8); - - // Initialize pawn attack bitboards for both sides - ei.attackedBy[WHITE][PAWN] = ei.pi->pawn_attacks(WHITE); - b = ei.attackedBy[WHITE][PAWN] & ei.attackedBy[BLACK][KING]; - if (b) - ei.kingAttackersCount[WHITE] = count_1s_max_15(b)/2; - - ei.attackedBy[BLACK][PAWN] = ei.pi->pawn_attacks(BLACK); - b = ei.attackedBy[BLACK][PAWN] & ei.attackedBy[WHITE][KING]; - if (b) - ei.kingAttackersCount[BLACK] = count_1s_max_15(b)/2; + // Initialize attack bitboards with pawns evaluation + init_attack_tables(pos, ei); + init_attack_tables(pos, ei); // Evaluate pieces evaluate_pieces_of_color(pos, ei); @@ -359,23 +348,23 @@ Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) { // Middle-game specific evaluation terms if (phase > PHASE_ENDGAME) { - // Pawn storms in positions with opposite castling - if ( square_file(pos.king_square(WHITE)) >= FILE_E - && square_file(pos.king_square(BLACK)) <= FILE_D) + // Pawn storms in positions with opposite castling + if ( square_file(pos.king_square(WHITE)) >= FILE_E + && square_file(pos.king_square(BLACK)) <= FILE_D) - ei.value += make_score(ei.pi->queenside_storm_value(WHITE) - ei.pi->kingside_storm_value(BLACK), 0); + ei.value += make_score(ei.pi->queenside_storm_value(WHITE) - ei.pi->kingside_storm_value(BLACK), 0); - else if ( square_file(pos.king_square(WHITE)) <= FILE_D - && square_file(pos.king_square(BLACK)) >= FILE_E) + else if ( square_file(pos.king_square(WHITE)) <= FILE_D + && square_file(pos.king_square(BLACK)) >= FILE_E) - ei.value += make_score(ei.pi->kingside_storm_value(WHITE) - ei.pi->queenside_storm_value(BLACK), 0); + ei.value += make_score(ei.pi->kingside_storm_value(WHITE) - ei.pi->queenside_storm_value(BLACK), 0); - // Evaluate space for both sides - if (ei.mi->space_weight() > 0) - { - evaluate_space(pos, ei); - evaluate_space(pos, ei); - } + // Evaluate space for both sides + if (ei.mi->space_weight() > 0) + { + evaluate_space(pos, ei); + evaluate_space(pos, ei); + } } // Mobility @@ -481,6 +470,23 @@ void read_weights(Color us) { namespace { + // init_king_tables() initializes king bitboards for both sides adding + // pawn attacks. To be done before other evaluations. + + template + void init_attack_tables(const Position& pos, EvalInfo& ei) { + + const Color Them = (Us == WHITE ? BLACK : WHITE); + + Bitboard b = ei.attackedBy[Them][KING] = pos.attacks_from(pos.king_square(Them)); + 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; + } + + // evaluate_outposts() evaluates bishop and knight outposts squares template @@ -556,7 +562,7 @@ namespace { ei.value -= Sign[Us] * ThreatedByPawnPenalty[Piece]; // Bishop and knight outposts squares - if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Them)) + if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Us)) evaluate_outposts(pos, ei, s); // Special patterns: trapped bishops on a7/h7/a2/h2 @@ -761,12 +767,6 @@ namespace { if (b) attackUnits += KnightCheckBonus * count_1s_max_15(b); - // Analyse enemy's discovered checks (only for non-pawns right now, - // consider adding pawns later). - b = pos.discovered_check_candidates(Them) & ~pos.pieces(PAWN); - if (b) - attackUnits += DiscoveredCheckBonus * count_1s_max_15(b) * (sente ? 2 : 1); - // To index KingDangerTable[] attackUnits must be in [0, 99] range attackUnits = Min(99, Max(0, attackUnits)); @@ -795,11 +795,10 @@ namespace { { Square s = pop_1st_bit(&b); - assert(pos.piece_on(s) == piece_of_color_and_type(Us, PAWN)); assert(pos.pawn_is_passed(Us, s)); int r = int(relative_rank(Us, s) - RANK_2); - int tr = Max(0, r * (r - 1)); + int tr = r * (r - 1); // Base bonus based on rank Value mbonus = Value(20 * tr); @@ -820,9 +819,6 @@ namespace { squaresToQueen = squares_in_front_of(Us, s); defendedSquares = squaresToQueen & ei.attacked_by(Us); - // There are no enemy pawns in the pawn's path - assert(!(squaresToQueen & pos.pieces(PAWN, Them))); - // If there is an enemy rook or queen attacking the pawn from behind, // add all X-ray attacks by the rook or queen. Otherwise consider only // the squares in the pawn's path attacked or occupied by the enemy. @@ -900,6 +896,7 @@ namespace { Square s = pop_1st_bit(&b); Square queeningSquare = relative_square(c, make_square(square_file(s), RANK_8)); int d = square_distance(s, queeningSquare) + - (relative_rank(c, s) == RANK_2) // Double pawn push - square_distance(pos.king_square(opposite_color(c)), queeningSquare) + int(c != pos.side_to_move()); @@ -1104,28 +1101,19 @@ namespace { void init_safety() { - int maxSlope = 30; - int peak = 0x500; - double a = 0.4; - double b = 0.0; + const Value MaxSlope = Value(30); + const Value Peak = Value(1280); Value t[100]; // First setup the base table for (int i = 0; i < 100; i++) { - if (i < b) - t[i] = Value(0); - else - t[i] = Value((int)(a * (i - b) * (i - b))); - } + t[i] = Value(int(0.4 * i * i)); - for (int i = 1; i < 100; i++) - { - if (t[i] - t[i - 1] > maxSlope) - t[i] = t[i - 1] + Value(maxSlope); + if (i > 0) + t[i] = Min(t[i], t[i - 1] + MaxSlope); - if (t[i] > Value(peak)) - t[i] = Value(peak); + t[i] = Min(t[i], Peak); } // Then apply the weights and get the final KingDangerTable[] array