-/// generate_next_stage() generates, scores, and sorts the next bunch of moves
-/// when there are no more moves to try for the current stage.
-
-void MovePicker::generate_next_stage() {
-
- assert(stage != STOP);
-
- cur = moves;
-
- switch (++stage) {
-
- case GOOD_CAPTURES: case QCAPTURES_1: case QCAPTURES_2:
- case PROBCUT_CAPTURES: case RECAPTURES:
- endMoves = generate<CAPTURES>(pos, moves);
- score<CAPTURES>();
- break;
-
- case KILLERS:
- killers[0] = ss->killers[0];
- killers[1] = ss->killers[1];
- killers[2] = countermove;
- cur = killers;
- endMoves = cur + 2 + (countermove != killers[0] && countermove != killers[1]);
- break;
-
- case QUIET:
- endMoves = generate<QUIETS>(pos, moves);
- score<QUIETS>();
- if (depth < 3 * ONE_PLY)
- {
- ExtMove* goodQuiet = std::partition(cur, endMoves, [](const ExtMove& m)
- { return m.value > VALUE_ZERO; });
- insertion_sort(cur, goodQuiet);
- } else
- insertion_sort(cur, endMoves);
- break;
-
- case BAD_CAPTURES:
- // Just pick them in reverse order to get correct ordering
- cur = moves + MAX_MOVES - 1;
- endMoves = endBadCaptures;
- break;
-
- case ALL_EVASIONS:
- endMoves = generate<EVASIONS>(pos, moves);
- if (endMoves - moves > 1)
- score<EVASIONS>();
- break;
-
- case CHECKS:
- endMoves = generate<QUIET_CHECKS>(pos, moves);
- break;
-
- case EVASION: case QSEARCH_WITH_CHECKS: case QSEARCH_WITHOUT_CHECKS:
- case PROBCUT: case RECAPTURE: case STOP:
- stage = STOP;
- break;
-
- default:
- assert(false);
- }
-}
+ 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>();
+ partial_insertion_sort(cur, endMoves, std::numeric_limits<int>::min());
+ ++stage;
+ goto top;
+
+ case GOOD_CAPTURE :
+ if (select<Next>([&]() {
+ // Move losing capture to endBadCaptures to be tried later
+ return pos.see_ge(*cur, Value(-cur->value)) ? true
+ : (*endBadCaptures++ = *cur, false);
+ }))
+ return *(cur - 1);
+
+ // 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 *cur != MOVE_NONE && !pos.capture_stage(*cur) && pos.pseudo_legal(*cur);
+ }))
+ return *(cur - 1);
+ ++stage;
+ [[fallthrough]];
+
+ case QUIET_INIT :
+ if (!skipQuiets)
+ {
+ cur = endBadCaptures;
+ endMoves = generate<QUIETS>(pos, cur);
+
+ score<QUIETS>();
+ partial_insertion_sort(cur, endMoves, -1960 - 3130 * depth);
+ }
+
+ ++stage;
+ [[fallthrough]];
+
+ case QUIET :
+ if (!skipQuiets && select<Next>([&]() {
+ return *cur != refutations[0].move && *cur != refutations[1].move
+ && *cur != refutations[2].move;
+ }))
+ return *(cur - 1);
+
+ // Prepare the pointers to loop over the bad captures
+ cur = moves;
+ endMoves = endBadCaptures;
+
+ ++stage;
+ [[fallthrough]];
+
+ case BAD_CAPTURE :
+ return select<Next>([]() { return true; });
+
+ case EVASION_INIT :
+ cur = moves;
+ endMoves = generate<EVASIONS>(pos, cur);
+
+ score<EVASIONS>();
+ ++stage;
+ [[fallthrough]];
+
+ case EVASION :
+ return select<Best>([]() { return true; });
+
+ case PROBCUT :
+ return select<Next>([&]() { return pos.see_ge(*cur, threshold); });
+
+ case QCAPTURE :
+ if (select<Next>([]() { return true; }))
+ return *(cur - 1);
+
+ // 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>([]() { return true; });
+ }