- static_assert(Type == CAPTURES || Type == QUIETS || Type == EVASIONS, "Wrong type");
-
- [[maybe_unused]] Bitboard threatenedByPawn, threatenedByMinor, threatenedByRook;
- if constexpr (Type == QUIETS)
- {
- Color us = pos.side_to_move();
-
- threatenedByPawn = pos.attacks_by<PAWN>(~us);
- threatenedByMinor = pos.attacks_by<KNIGHT>(~us) | pos.attacks_by<BISHOP>(~us) | threatenedByPawn;
- threatenedByRook = pos.attacks_by<ROOK>(~us) | threatenedByMinor;
-
- // Pieces threatened by pieces of lesser material value
- threatenedPieces = (pos.pieces(us, QUEEN) & threatenedByRook)
- | (pos.pieces(us, ROOK) & threatenedByMinor)
- | (pos.pieces(us, KNIGHT, BISHOP) & threatenedByPawn);
- }
-
- for (auto& m : *this)
- if constexpr (Type == CAPTURES)
- m.value = (7 * int(PieceValue[MG][pos.piece_on(to_sq(m))])
- + (*captureHistory)[pos.moved_piece(m)][to_sq(m)][type_of(pos.piece_on(to_sq(m)))]) / 16;
-
- else if constexpr (Type == QUIETS)
- m.value = 2 * (*mainHistory)[pos.side_to_move()][from_to(m)]
- + 2 * (*continuationHistory[0])[pos.moved_piece(m)][to_sq(m)]
- + (*continuationHistory[1])[pos.moved_piece(m)][to_sq(m)]
- + (*continuationHistory[3])[pos.moved_piece(m)][to_sq(m)]
- + (*continuationHistory[5])[pos.moved_piece(m)][to_sq(m)]
- + (threatenedPieces & from_sq(m) ?
- (type_of(pos.moved_piece(m)) == QUEEN && !(to_sq(m) & threatenedByRook) ? 50000
- : type_of(pos.moved_piece(m)) == ROOK && !(to_sq(m) & threatenedByMinor) ? 25000
- : !(to_sq(m) & threatenedByPawn) ? 15000
- : 0)
- : 0)
- + bool(pos.check_squares(type_of(pos.moved_piece(m))) & to_sq(m)) * 16384;
- else // Type == EVASIONS
- {
- if (pos.capture(m))
- m.value = PieceValue[MG][pos.piece_on(to_sq(m))]
- - Value(type_of(pos.moved_piece(m)))
- + (1 << 28);
- else
- m.value = (*mainHistory)[pos.side_to_move()][from_to(m)]
- + (*continuationHistory[0])[pos.moved_piece(m)][to_sq(m)];
- }
+ static_assert(Type == CAPTURES || Type == QUIETS || Type == EVASIONS, "Wrong type");
+
+ [[maybe_unused]] Bitboard threatenedByPawn, threatenedByMinor, threatenedByRook,
+ threatenedPieces;
+ if constexpr (Type == QUIETS)
+ {
+ Color us = pos.side_to_move();
+
+ threatenedByPawn = pos.attacks_by<PAWN>(~us);
+ threatenedByMinor =
+ pos.attacks_by<KNIGHT>(~us) | pos.attacks_by<BISHOP>(~us) | threatenedByPawn;
+ threatenedByRook = pos.attacks_by<ROOK>(~us) | threatenedByMinor;
+
+ // Pieces threatened by pieces of lesser material value
+ threatenedPieces = (pos.pieces(us, QUEEN) & threatenedByRook)
+ | (pos.pieces(us, ROOK) & threatenedByMinor)
+ | (pos.pieces(us, KNIGHT, BISHOP) & threatenedByPawn);
+ }
+
+ for (auto& m : *this)
+ if constexpr (Type == CAPTURES)
+ m.value =
+ 7 * int(PieceValue[pos.piece_on(m.to_sq())])
+ + (*captureHistory)[pos.moved_piece(m)][m.to_sq()][type_of(pos.piece_on(m.to_sq()))];
+
+ else if constexpr (Type == QUIETS)
+ {
+ Piece pc = pos.moved_piece(m);
+ PieceType pt = type_of(pc);
+ Square from = m.from_sq();
+ Square to = m.to_sq();
+
+ // histories
+ m.value = (*mainHistory)[pos.side_to_move()][m.from_to()];
+ m.value += 2 * (*pawnHistory)[pawn_structure_index(pos)][pc][to];
+ m.value += 2 * (*continuationHistory[0])[pc][to];
+ m.value += (*continuationHistory[1])[pc][to];
+ m.value += (*continuationHistory[2])[pc][to] / 3;
+ m.value += (*continuationHistory[3])[pc][to];
+ m.value += (*continuationHistory[5])[pc][to];
+
+ // bonus for checks
+ m.value += bool(pos.check_squares(pt) & to) * 16384;
+
+ // bonus for escaping from capture
+ m.value += threatenedPieces & from ? (pt == QUEEN && !(to & threatenedByRook) ? 51700
+ : pt == ROOK && !(to & threatenedByMinor) ? 25600
+ : !(to & threatenedByPawn) ? 14450
+ : 0)
+ : 0;
+
+ // malus for putting piece en prise
+ m.value -= (pt == QUEEN ? bool(to & threatenedByRook) * 49000
+ : pt == ROOK ? bool(to & threatenedByMinor) * 24335
+ : bool(to & threatenedByPawn) * 14900);
+ }
+
+ else // Type == EVASIONS
+ {
+ if (pos.capture_stage(m))
+ m.value =
+ PieceValue[pos.piece_on(m.to_sq())] - type_of(pos.moved_piece(m)) + (1 << 28);
+ else
+ m.value = (*mainHistory)[pos.side_to_move()][m.from_to()]
+ + (*continuationHistory[0])[pos.moved_piece(m)][m.to_sq()]
+ + (*pawnHistory)[pawn_structure_index(pos)][pos.moved_piece(m)][m.to_sq()];
+ }