constexpr Score MinorBehindPawn = S( 16, 0);
constexpr Score Overload = S( 12, 6);
constexpr Score PawnlessFlank = S( 18, 94);
+ constexpr Score RestrictedPiece = S( 7, 6);
constexpr Score RookOnPawn = S( 10, 28);
constexpr Score SliderOnQueen = S( 49, 21);
constexpr Score ThreatByKing = S( 21, 84);
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
- Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
+ Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe, restricted;
Score score = SCORE_ZERO;
// Non-pawn enemies
score += Overload * popcount(b);
}
+ // Bonus for restricting their piece moves
+ restricted = attackedBy[Them][ALL_PIECES]
+ & ~attackedBy[Them][PAWN]
+ & ~attackedBy2[Them]
+ & attackedBy[Us][ALL_PIECES];
+ score += RestrictedPiece * popcount(restricted);
+
// Bonus for enemy unopposed weak pawns
if (pos.pieces(Us, ROOK, QUEEN))
score += WeakUnopposedPawn * pe->weak_unopposed(Them);
return d > 17 ? 0 : 29 * d * d + 138 * d - 134;
}
- // Add a small random component to draw evaluations to keep search dynamic
+ // Add a small random component to draw evaluations to keep search dynamic
// and to avoid 3fold-blindness.
Value value_draw(Depth depth, Thread* thisThread) {
- return depth < 4 ? VALUE_DRAW
+ return depth < 4 ? VALUE_DRAW
: VALUE_DRAW + Value(2 * (thisThread->nodes.load(std::memory_order_relaxed) % 2) - 1);
}
if ( Threads.stop.load(std::memory_order_relaxed)
|| pos.is_draw(ss->ply)
|| ss->ply >= MAX_PLY)
- return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos)
+ return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos)
: value_draw(depth, pos.this_thread());
// Step 3. Mate distance pruning. Even if we mate at the next move our score