X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fevaluate.cpp;h=82edeec8ac0c43b666ea6df70d728da0989b62b9;hb=70b7404a63b74a57d4e1d0b9192b00837e9a1af8;hp=6ef8e18337e3507d6ee155b8e49970a2ae03a4b9;hpb=73da3a431c6d2c9e3391a796c1bebf9967e27a25;p=stockfish diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 6ef8e183..82edeec8 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -241,6 +241,40 @@ namespace { // Bonus for having a mate threat, initialized from UCI options int MateThreatBonus; + // ThreatBonus[][] contains bonus according to which piece type + // attacks which one. + const Value MidgameThreatBonus[8][8] = { + { V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) }, // not used + { V(0),V(18), V(0),V(37), V(55), V(55), V(0), V(0) }, // KNIGHT attacks + { V(0),V(18),V(37), V(0), V(55), V(55), V(0), V(0) }, // BISHOP attacks + { V(0), V(9),V(27),V(27), V(0), V(37), V(0), V(0) }, // ROOK attacks + { V(0),V(27),V(27),V(27), V(27), V(0), V(0), V(0) }, // QUEEN attacks + { V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) }, // not used + { V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) }, // not used + { V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) } // not used + }; + + const Value EndgameThreatBonus[8][8] = { + { V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) }, // not used + { V(0),V(37), V(0),V(47), V(97), V(97), V(0), V(0) }, // KNIGHT attacks + { V(0),V(37),V(47), V(0), V(97), V(97), V(0), V(0) }, // BISHOP attacks + { V(0),V(27),V(47),V(47), V(0), V(47), V(0), V(0) }, // ROOK attacks + { V(0),V(37),V(37),V(37), V(37), V(0), V(0), V(0) }, // QUEEN attacks + { V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) }, // not used + { V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) }, // not used + { V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) } // not used + }; + + // ThreatedByPawnPenalty[] contains a penalty according to which piece + // type is attacked by an enemy pawn. + const Value MidgameThreatedByPawnPenalty[8] = { + V(0), V(0), V(56), V(56), V(76), V(86), V(0), V(0) + }; + + const Value EndgameThreatedByPawnPenalty[8] = { + V(0), V(0), V(70), V(70), V(99), V(118), V(0), V(0) + }; + // InitKingDanger[] contains bonuses based on the position of the defending // king. const int InitKingDanger[64] = { @@ -276,6 +310,9 @@ namespace { template void evaluate_king(const Position& pos, EvalInfo& ei); + template + void evaluate_threats(const Position& pos, EvalInfo& ei); + template void evaluate_space(const Position& pos, EvalInfo& ei); @@ -365,6 +402,10 @@ Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) { evaluate_king(pos, ei); evaluate_king(pos, ei); + // Evaluate tactical threats, we need full attack info + evaluate_threats(pos, ei); + evaluate_threats(pos, ei); + // Evaluate passed pawns. We evaluate passed pawns for both sides at once, // because we need to know which side promotes first in positions where // both sides have an unstoppable passed pawn. To be called after all attacks @@ -531,13 +572,12 @@ namespace { // evaluate_mobility() computes mobility and attacks for every piece template - int evaluate_mobility(const Position& pos, Bitboard b, Bitboard mob_area, EvalInfo& ei) { + int evaluate_mobility(Bitboard b, Bitboard mob_area, EvalInfo& ei) { const Color Them = (Us == WHITE ? BLACK : WHITE); static const int AttackWeight[] = { 0, 0, KnightAttackWeight, BishopAttackWeight, RookAttackWeight, QueenAttackWeight }; static const Value* MgBonus[] = { 0, 0, MidgameKnightMobilityBonus, MidgameBishopMobilityBonus, MidgameRookMobilityBonus, MidgameQueenMobilityBonus }; static const Value* EgBonus[] = { 0, 0, EndgameKnightMobilityBonus, EndgameBishopMobilityBonus, EndgameRookMobilityBonus, EndgameQueenMobilityBonus }; - static const int lastIndex[] = { 0, 0, 8, 15, 15, 31 }; // Update attack info ei.attackedBy[Us][Piece] |= b; @@ -552,20 +592,9 @@ namespace { ei.kingAdjacentZoneAttacksCount[Us] += count_1s_max_15(bb); } - // The squares occupied by enemy pieces (not defended by pawns) will be - // counted two times instead of one. The shift (almost) guarantees that - // intersection of the shifted value with b is zero so that after or-ing - // the count of 1s bits is increased by the number of affected squares. - b &= mob_area; - b |= Us == WHITE ? ((b & pos.pieces_of_color(Them)) >> 1) - : ((b & pos.pieces_of_color(Them)) << 1); - // Mobility - int mob = (Piece != QUEEN ? count_1s_max_15(b) - : count_1s(b)); - - if (mob > lastIndex[Piece]) - mob = lastIndex[Piece]; + int mob = (Piece != QUEEN ? count_1s_max_15(b & mob_area) + : count_1s(b & mob_area)); ei.mgMobility += Sign[Us] * MgBonus[Piece][mob]; ei.egMobility += Sign[Us] * EgBonus[Piece][mob]; @@ -627,7 +656,15 @@ namespace { assert(false); // Attacks and mobility - mob = evaluate_mobility(pos, b, mob_area, ei); + mob = evaluate_mobility(b, mob_area, ei); + + // 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. + if (bit_is_set(ei.attackedBy[Them][PAWN], s)) + { + ei.mgValue -= Sign[Us] * MidgameThreatedByPawnPenalty[Piece]; + ei.egValue -= Sign[Us] * EndgameThreatedByPawnPenalty[Piece]; + } // Bishop and knight outposts squares if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Them)) @@ -704,6 +741,44 @@ namespace { } + // evaluate_threats<>() assigns bonuses according to the type of attacking piece + // and the type of attacked one. + + template + void evaluate_threats(const Position& pos, EvalInfo& ei) { + + const Color Them = (Us == WHITE ? BLACK : WHITE); + + Bitboard b; + Value mgBonus = Value(0); + Value egBonus = Value(0); + + // Enemy pieces not defended by a pawn and under our attack + Bitboard weakEnemies = pos.pieces_of_color(Them) + & ~ei.attackedBy[Them][PAWN] + & ei.attackedBy[Us][0]; + if (!weakEnemies) + return; + + // Add bonus according to type of attacked enemy pieces and to the + // type of attacking piece, from knights to queens. Kings are not + // considered because are already special handled in king evaluation. + for (PieceType pt1 = KNIGHT; pt1 < KING; pt1++) + { + b = ei.attackedBy[Us][pt1] & weakEnemies; + if (b) + for (PieceType pt2 = PAWN; pt2 < KING; pt2++) + if (b & pos.pieces(pt2)) + { + mgBonus += MidgameThreatBonus[pt1][pt2]; + egBonus += EndgameThreatBonus[pt1][pt2]; + } + } + ei.mgValue += Sign[Us] * mgBonus; + ei.egValue += Sign[Us] * egBonus; + } + + // evaluate_pieces_of_color<>() assigns bonuses and penalties to all the // pieces of a given color. @@ -1096,8 +1171,8 @@ namespace { Square b8 = relative_square(us, (square_file(s) == FILE_A) ? SQ_B8 : SQ_G8); if ( pos.piece_on(b6) == piece_of_color_and_type(opposite_color(us), PAWN) - && pos.see(s, b6) < 0 - && pos.see(s, b8) < 0) + && pos.see(s, b6, false) < 0 + && pos.see(s, b8, false) < 0) { ei.mgValue -= Sign[us] * TrappedBishopA7H7Penalty; ei.egValue -= Sign[us] * TrappedBishopA7H7Penalty;