if (Pt == BISHOP || Pt == KNIGHT)
{
- // Bonus if piece is on an outpost square or can reach one
+ // Bonus if the piece is on an outpost square or can reach one
+ // Reduced bonus for knights (BadOutpost) if few relevant targets
bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
+ Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
+
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)))
+ && bb & s & ~CenterFiles // on a side outpost
+ && !(b & targets) // no relevant attacks
+ && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
score += BadOutpost;
else if (bb & s)
score += Outpost[Pt == BISHOP];
// Bonus for threats on the next moves against enemy queen
if (pos.count<QUEEN>(Them) == 1)
{
+ bool queenImbalance = pos.count<QUEEN>() == 1;
+
Square s = pos.square<QUEEN>(Them);
- safe = mobilityArea[Us] & ~stronglyProtected;
+ safe = mobilityArea[Us]
+ & ~pos.pieces(Us, PAWN)
+ & ~stronglyProtected;
b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
- score += KnightOnQueen * popcount(b & safe);
+ score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
| (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
- score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]);
+ score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
}
if (T)