@@ -6,37 +6,83 @@ using namespace chess;
66using engine::eval::piece_value;
77namespace engine ::movepick {
88
9- void orderMoves (chess::Board &board, chess::Movelist &moves, chess::Move ttMove,
10- int ply, const engine::search::Session &session) {
11- std::vector<std::pair<chess::Move, Value>> scoredMoves;
12- scoredMoves.reserve (moves.size ());
13-
14- for (const auto &move : moves) {
15- Value score = 0 ;
16-
17- if (move == ttMove)
18- score = 10000 ;
19- else if (board.isCapture (move))
20- score = ((move.type_of () & EN_PASSANT ) == 0
21- ? piece_value (board.at <PieceType>(move.to ()))
22- : piece_value (PAWN )) *
23- 10 -
24- piece_value (board.at <PieceType>(move.from ()));
25- else if (move == session.killerMoves [ply][0 ])
26- score = 8500 ;
27- else if (move == session.killerMoves [ply][1 ])
28- score = 8000 ;
29- else
30- score = session.historyHeuristic [move.from ()][move.to ()];
31-
32- scoredMoves.emplace_back (move, score);
33- }
9+ static Bitboard att (PieceType pt, Square sq, Bitboard occ) {
10+ switch (pt) {
11+ case BISHOP : return attacks::bishop (sq, occ);
12+ case ROOK : return attacks::rook (sq, occ);
13+ case QUEEN : return attacks::queen (sq, occ);
14+ default : return 0 ;
15+ }
16+ }
3417
35- std::stable_sort (
36- scoredMoves.begin (), scoredMoves.end (),
37- [](const auto &a, const auto &b) { return a.second > b.second ; });
18+ Value see (Board& board, Move move) {
19+ if (move.type_of () == EN_PASSANT )
20+ return piece_value (PAWN );
21+ PieceType captured = board.at <PieceType>(move.to ());
22+ if (captured == NO_PIECE_TYPE )
23+ return 0 ;
24+ PieceType attacker = board.at <PieceType>(move.from ());
25+ Bitboard occ = board.occ () ^ (1ULL << move.from ());
26+ Bitboard attackers = board.attackers (WHITE , move.to (), occ) | board.attackers (BLACK , move.to (), occ);
27+ Value gain[32 ];
28+ int d = 0 ;
29+ gain[d] = piece_value (captured);
30+ Color stm = ~board.side_to_move ();
31+ while (++d < 32 ) {
32+ gain[d] = piece_value (attacker) - gain[d - 1 ];
33+ if (gain[d] < 0 )
34+ break ;
35+ attackers &= occ;
36+ Bitboard stmAttackers = attackers & board.occ (stm);
37+ if (!stmAttackers)
38+ break ;
39+ Square sq = (Square)pop_lsb (stmAttackers);
40+ attacker = board.at <PieceType>(sq);
41+ if (attacker == NO_PIECE_TYPE )
42+ break ;
43+ if (attacker == BISHOP || attacker == ROOK || attacker == QUEEN )
44+ attackers |= att (attacker, move.to (), occ);
45+ occ ^= (1ULL << sq);
46+ stm = ~stm;
47+ }
48+ while (--d)
49+ gain[d - 1 ] = -gain[d];
50+ return gain[0 ];
51+ }
3852
39- for (size_t i = 0 ; i < scoredMoves.size (); ++i)
40- moves[i] = scoredMoves[i].first ;
53+ void orderMoves (Board &board, Movelist &moves, Move ttMove, int ply, const engine::search::Session &session, Move prevMove) {
54+ Value scores[300 ];
55+ size_t n = moves.size ();
56+ for (size_t i = 0 ; i < n; ++i) {
57+ Move move = moves[i];
58+ if (move == ttMove)
59+ scores[i] = 10000 ;
60+ else if (board.isCapture (move)) {
61+ Value s = see (board, move);
62+ Value capturedVal = move.type_of () == EN_PASSANT ? piece_value (PAWN ) : piece_value (board.at <PieceType>(move.to ()));
63+ Value attackerVal = piece_value (board.at <PieceType>(move.from ()));
64+ scores[i] = (s >= -50 ? 9000 : 4000 ) + std::max (s, Value (-50 )) + (capturedVal * 10 - attackerVal) / 100 ;
65+ } else if (move == session.killerMoves [ply][0 ])
66+ scores[i] = 8500 ;
67+ else if (move == session.killerMoves [ply][1 ])
68+ scores[i] = 8000 ;
69+ else if (prevMove.is_ok () && move == session.counterMoves [prevMove.from_to ()])
70+ scores[i] = 7500 ;
71+ else if (board.givesCheck (move) != CheckType::NO_CHECK )
72+ scores[i] = 7000 ;
73+ else
74+ scores[i] = session.historyHeuristic [move.from ()][move.to ()];
75+ }
76+ size_t limit = std::min (n, size_t (12 ));
77+ for (size_t i = 0 ; i + 1 < limit; ++i) {
78+ size_t best = i;
79+ for (size_t j = i + 1 ; j < n; ++j)
80+ if (scores[j] > scores[best])
81+ best = j;
82+ if (best != i) {
83+ std::swap (moves[i], moves[best]);
84+ std::swap (scores[i], scores[best]);
85+ }
86+ }
4187}
42- } // namespace engine::movepick
88+ } // namespace engine::movepick
0 commit comments