- return pos.piece_count(Us, PAWN) == 0
- && pos.non_pawn_material(Us) == QueenValueMg
- && pos.piece_count(Us, QUEEN) == 1
- && pos.piece_count(Them, ROOK) == 1
- && pos.piece_count(Them, PAWN) >= 1;
+ return !pos.count<PAWN>(Us)
+ && pos.non_pawn_material(Us) == QueenValueMg
+ && pos.count<QUEEN>(Us) == 1
+ && pos.count<ROOK>(Them) == 1
+ && pos.count<PAWN>(Them) >= 1;
+ }
+
+ /// imbalance() calculates the imbalance by comparing the piece count of each
+ /// piece type for both colors.
+
+ template<Color Us>
+ int imbalance(const int pieceCount[][PIECE_TYPE_NB]) {
+
+ const Color Them = (Us == WHITE ? BLACK : WHITE);
+
+ int pt1, pt2, pc, v;
+ int value = 0;
+
+ // Second-degree polynomial material imbalance by Tord Romstad
+ for (pt1 = NO_PIECE_TYPE; pt1 <= QUEEN; ++pt1)
+ {
+ pc = pieceCount[Us][pt1];
+ if (!pc)
+ continue;
+
+ v = LinearCoefficients[pt1];
+
+ for (pt2 = NO_PIECE_TYPE; pt2 <= pt1; ++pt2)
+ v += QuadraticCoefficientsSameColor[pt1][pt2] * pieceCount[Us][pt2]
+ + QuadraticCoefficientsOppositeColor[pt1][pt2] * pieceCount[Them][pt2];
+
+ value += pc * v;
+ }
+
+ // Queen vs. 3 minors slightly favours the minors
+ if (pieceCount[Us][QUEEN] == 1 && pieceCount[Them][QUEEN] == 0)
+ {
+ int n = pieceCount[Them][KNIGHT] - pieceCount[Us][KNIGHT];
+ int b = pieceCount[Them][BISHOP] - pieceCount[Us][BISHOP];
+
+ if ((n == 2 && b == 1) || (n == 1 && b == 2))
+ value -= 66 * 16;
+ }
+
+ return value;