- CACHE_LINE_ALIGNMENT
- const MovegenPhaseT MainSearchPhaseTable[] = { PH_TT_MOVES, PH_GOOD_CAPTURES, PH_KILLERS, PH_NONCAPTURES, PH_BAD_CAPTURES, PH_STOP};
- const MovegenPhaseT EvasionsPhaseTable[] = { PH_EVASIONS, PH_STOP};
- const MovegenPhaseT QsearchWithChecksPhaseTable[] = { PH_TT_MOVES, PH_QCAPTURES, PH_QCHECKS, PH_STOP};
- const MovegenPhaseT QsearchWithoutChecksPhaseTable[] = { PH_TT_MOVES, PH_QCAPTURES, PH_STOP};
+ enum Sequencer {
+ MAIN_SEARCH, TT_MOVE_S1, GOOD_CAPTURES_S1, KILLERS_S1, NONCAPTURES_1_S1,
+ NONCAPTURES_2_S1, BAD_CAPTURES_S1, STOP_S1,
+ EVASIONS, TT_MOVE_S2, EVASIONS_S2, STOP_S2,
+ CAPTURES_AND_CHECKS, TT_MOVE_S3, QCAPTURES_S3, QCHECKS_S3, STOP_S3,
+ CAPTURES, TT_MOVE_S4, QCAPTURES_S4, STOP_S4,
+ RECAPTURES, TT_MOVE_S5, RECAPTURES_S5, STOP_S5,
+ PROBCUT, TT_MOVE_S6, GOOD_CAPTURES_S6, STOP_S6
+ };
+
+ // Unary predicate used by std::partition to split positive scores from remaining
+ // ones so to sort separately the two sets, and with the second sort delayed.
+ inline bool has_positive_score(const MoveStack& move) { return move.score > 0; }
+
+ // Picks and pushes to the front the best move in range [firstMove, lastMove),
+ // it is faster than sorting all the moves in advance when moves are few, as
+ // normally are the possible captures.
+ inline MoveStack* pick_best(MoveStack* firstMove, MoveStack* lastMove)
+ {
+ std::swap(*firstMove, *std::max_element(firstMove, lastMove));
+ return firstMove;
+ }