+ // evaluate_threats() assigns bonuses according to the type of attacking piece
+ // and the type of attacked one.
+
+ template<Color Us, bool Trace>
+ Score evaluate_threats(const Position& pos, const EvalInfo& ei) {
+
+ const Color Them = (Us == WHITE ? BLACK : WHITE);
+
+ Bitboard b, undefendedMinors, weakEnemies;
+ Score score = SCORE_ZERO;
+
+ // Undefended minors get penalized even if they are not under attack
+ undefendedMinors = pos.pieces(Them, BISHOP, KNIGHT)
+ & ~ei.attackedBy[Them][ALL_PIECES];
+
+ if (undefendedMinors)
+ score += UndefendedMinor;
+
+ // Enemy pieces not defended by a pawn and under our attack
+ weakEnemies = pos.pieces(Them)
+ & ~ei.attackedBy[Them][PAWN]
+ & ei.attackedBy[Us][ALL_PIECES];
+
+ // Add bonus according to type of attacked enemy piece and to the
+ // type of attacking piece, from knights to queens. Kings are not
+ // considered because they are already handled in king evaluation.
+ if (weakEnemies)
+ 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))
+ score += Threat[pt1][pt2];
+ }
+
+ if (Trace)
+ Tracing::scores[Us][THREAT] = score;
+
+ return score;
+ }
+
+
+ // evaluate_passed_pawns() evaluates the passed pawns of the given color