-/// MovePicker::get_next_move() is the most important method of the MovePicker
-/// class. It returns a new legal move every time it is called, until there
-/// are no more moves left.
-/// It picks the move with the biggest score from a list of generated moves taking
-/// care not to return the tt move if has already been searched previously.
-/// Note that this function is not thread safe so should be lock protected by
-/// caller when accessed through a shared MovePicker object.
-
-Move MovePicker::get_next_move() {
-
- Move move;
-
- while (true)
- {
- while (curMove != lastMove)
- {
- switch (phase) {
-
- case PH_TT_MOVES:
- move = (curMove++)->move;
- if ( move != MOVE_NONE
- && pos.move_is_legal(move, pinned))
- return move;
- break;
-
- case PH_GOOD_CAPTURES:
- move = pick_best(curMove++, lastMove).move;
- if ( move != ttMoves[0].move
- && move != ttMoves[1].move
- && pos.pl_move_is_legal(move, pinned))
- {
- // Check for a non negative SEE now
- int seeValue = pos.see_sign(move);
- if (seeValue >= badCaptureThreshold)
- return move;
-
- // Losing capture, move it to the tail of the array, note
- // that move has now been already checked for legality.
- (--badCaptures)->move = move;
- badCaptures->score = seeValue;
- }
- break;
-
- case PH_KILLERS:
- move = (curMove++)->move;
- if ( move != MOVE_NONE
- && pos.move_is_legal(move, pinned)
- && move != ttMoves[0].move
- && move != ttMoves[1].move
- && !pos.move_is_capture(move))
- return move;
- break;
-
- case PH_NONCAPTURES:
-
- // Sort negative scored moves only when we get there
- if (curMove == lastGoodNonCapture)
- insertion_sort<MoveStack>(lastGoodNonCapture, lastMove);
-
- move = (curMove++)->move;
- if ( move != ttMoves[0].move
- && move != ttMoves[1].move
- && move != killers[0].move
- && move != killers[1].move
- && pos.pl_move_is_legal(move, pinned))
- return move;
- break;
-
- case PH_BAD_CAPTURES:
- move = pick_best(curMove++, lastMove).move;
- return move;
-
- case PH_EVASIONS:
- case PH_QCAPTURES:
- move = pick_best(curMove++, lastMove).move;
- if ( move != ttMoves[0].move
- && pos.pl_move_is_legal(move, pinned))
- return move;
- break;
-
- case PH_QCHECKS:
- move = (curMove++)->move;
- if ( move != ttMoves[0].move
- && pos.pl_move_is_legal(move, pinned))
- return move;
- break;
-
- case PH_STOP:
- return MOVE_NONE;
-
- default:
- assert(false);
- break;
- }
- }
- go_next_phase();
+/// MovePicker::next_move() is the most important method of the MovePicker class. It
+/// returns a new pseudo legal move every time it is called until there are no more
+/// moves left, picking the move with the highest score from a list of generated moves.
+Move MovePicker::next_move(bool skipQuiets) {
+
+top:
+ switch (stage) {
+
+ case MAIN_TT:
+ case EVASION_TT:
+ case QSEARCH_TT:
+ case PROBCUT_TT:
+ ++stage;
+ return ttMove;
+
+ case CAPTURE_INIT:
+ case PROBCUT_INIT:
+ case QCAPTURE_INIT:
+ cur = endBadCaptures = moves;
+ endMoves = generate<CAPTURES>(pos, cur);
+
+ score<CAPTURES>();
+ ++stage;
+ goto top;
+
+ case GOOD_CAPTURE:
+ if (select<Best>([&](){
+ return pos.see_ge(move, Value(-55 * (cur-1)->value / 1024)) ?
+ // Move losing capture to endBadCaptures to be tried later
+ true : (*endBadCaptures++ = move, false); }))
+ return move;
+
+ // Prepare the pointers to loop over the refutations array
+ cur = std::begin(refutations);
+ endMoves = std::end(refutations);
+
+ // If the countermove is the same as a killer, skip it
+ if ( refutations[0].move == refutations[2].move
+ || refutations[1].move == refutations[2].move)
+ --endMoves;
+
+ ++stage;
+ /* fallthrough */
+
+ case REFUTATION:
+ if (select<Next>([&](){ return move != MOVE_NONE
+ && !pos.capture(move)
+ && pos.pseudo_legal(move); }))
+ return move;
+ ++stage;
+ /* fallthrough */
+
+ case QUIET_INIT:
+ cur = endBadCaptures;
+ endMoves = generate<QUIETS>(pos, cur);
+
+ score<QUIETS>();
+ partial_insertion_sort(cur, endMoves, -4000 * depth / ONE_PLY);
+ ++stage;
+ /* fallthrough */
+
+ case QUIET:
+ if ( !skipQuiets
+ && select<Next>([&](){return move != refutations[0]
+ && move != refutations[1]
+ && move != refutations[2];}))
+ return move;
+
+ // Prepare the pointers to loop over the bad captures
+ cur = moves;
+ endMoves = endBadCaptures;
+
+ ++stage;
+ /* fallthrough */
+
+ case BAD_CAPTURE:
+ return select<Next>(Any);
+
+ case EVASION_INIT:
+ cur = moves;
+ endMoves = generate<EVASIONS>(pos, cur);
+
+ score<EVASIONS>();
+ ++stage;
+ /* fallthrough */
+
+ case EVASION:
+ return select<Best>(Any);
+
+ case PROBCUT:
+ return select<Best>([&](){ return pos.see_ge(move, threshold); });
+
+ case QCAPTURE:
+ if (select<Best>([&](){ return depth > DEPTH_QS_RECAPTURES
+ || to_sq(move) == recaptureSquare; }))
+ return move;
+
+ // If we did not find any move and we do not try checks, we have finished
+ if (depth != DEPTH_QS_CHECKS)
+ return MOVE_NONE;
+
+ ++stage;
+ /* fallthrough */
+
+ case QCHECK_INIT:
+ cur = moves;
+ endMoves = generate<QUIET_CHECKS>(pos, cur);
+
+ ++stage;
+ /* fallthrough */
+
+ case QCHECK:
+ return select<Next>(Any);