constexpr Score KnightOnQueen = S( 21, 11);
constexpr Score LongDiagonalBishop = S( 22, 0);
constexpr Score MinorBehindPawn = S( 16, 0);
+ constexpr Score Overload = S( 10, 5);
constexpr Score PawnlessFlank = S( 20, 80);
constexpr Score RookOnPawn = S( 8, 24);
constexpr Score SliderOnQueen = S( 42, 21);
Bitboard b, bb;
Square s;
Score score = SCORE_ZERO;
+ int mob;
attackedBy[Us][Pt] = 0;
kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
}
- int mob = popcount(b & mobilityArea[Us]);
+ mob = (Pt == KNIGHT || Pt == BISHOP) ? popcount(b & mobilityArea[Us] & ~pos.pieces(Us, QUEEN))
+ : popcount(b & mobilityArea[Us]);
mobility[Us] += MobilityBonus[Pt - 2][mob];
Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safeThreats;
Score score = SCORE_ZERO;
- // Non-pawn enemies attacked by a pawn
+ // Non-pawn enemies
nonPawnEnemies = pos.pieces(Them) ^ pos.pieces(Them, PAWN);
- weak = nonPawnEnemies & attackedBy[Us][PAWN];
-
- if (weak)
- {
- // Our safe or protected pawns
- b = pos.pieces(Us, PAWN)
- & (~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES]);
-
- safeThreats = pawn_attacks_bb<Us>(b) & weak;
- score += ThreatBySafePawn * popcount(safeThreats);
- }
// Squares strongly protected by the enemy, either because they defend the
// square with a pawn, or because they defend the square twice and we don't.
score += ThreatByRank * (int)relative_rank(Them, s);
}
- score += Hanging * popcount(weak & ~attackedBy[Them][ALL_PIECES]);
-
b = weak & attackedBy[Us][KING];
if (b)
score += ThreatByKing[more_than_one(b)];
+
+ score += Hanging * popcount(weak & ~attackedBy[Them][ALL_PIECES]);
+
+ // Bonus for overload (non-pawn enemies attacked and defended exactly once)
+ b = nonPawnEnemies
+ & attackedBy[Us][ALL_PIECES] & ~attackedBy2[Us]
+ & attackedBy[Them][ALL_PIECES] & ~attackedBy2[Them];
+ score += Overload * popcount(b);
}
// Bonus for enemy unopposed weak pawns
if (pos.pieces(Us, ROOK, QUEEN))
score += WeakUnopposedPawn * pe->weak_unopposed(Them);
+ // Our safe or protected pawns
+ b = pos.pieces(Us, PAWN)
+ & (~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES]);
+
+ safeThreats = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
+ score += ThreatBySafePawn * popcount(safeThreats);
+
// Find squares where our pawns can push on the next move
b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
// pawn, or if it is undefended and attacked by an enemy piece.
Bitboard safe = SpaceMask
& ~pos.pieces(Us, PAWN)
- & ~attackedBy[Them][PAWN]
- & (attackedBy[Us][ALL_PIECES] | ~attackedBy[Them][ALL_PIECES]);
+ & ~attackedBy[Them][PAWN];
// Find all squares which are at most three squares behind some friendly pawn
Bitboard behind = pos.pieces(Us, PAWN);