diff --git a/src/bitboard.h b/src/bitboard.h index afeb40ec146..15ec4153362 100644 --- a/src/bitboard.h +++ b/src/bitboard.h @@ -130,6 +130,13 @@ constexpr bool more_than_one(Bitboard b) { return b & (b - 1); } +/// Counts the occupation of the bitboard depending on the occupation of SQ_A1 +/// as in `b & (1ULL << SQ_A1) ? more_than_two(b) : more_than_one(b)` + +constexpr bool conditional_more_than_two(Bitboard b) { + return b & (b - 1) & (b - 2); +} + constexpr bool opposite_colors(Square s1, Square s2) { return (s1 + rank_of(s1) + s2 + rank_of(s2)) & 1; } diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 6f2dd69ba33..ca6ea5c44fd 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -134,6 +134,7 @@ namespace { }; // Assorted bonuses and penalties + constexpr Score BadOutpost = S( -7, 36); constexpr Score BishopOnKingRing = S( 24, 0); constexpr Score BishopPawns = S( 3, 7); constexpr Score BishopXRayPawns = S( 4, 5); @@ -310,7 +311,13 @@ namespace { { // Bonus if piece is on an outpost square or can reach one bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them); - if (bb & s) + if ( Pt == KNIGHT + && bb & s & ~CenterFiles + && !(b & pos.pieces(Them) & ~pos.pieces(PAWN)) + && !conditional_more_than_two( + pos.pieces(Them) & ~pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide))) + score += BadOutpost; + else if (bb & s) score += Outpost[Pt == BISHOP]; else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us)) score += ReachableOutpost;