- while(true) {
- // If we already have a list of generated moves, pick the best move from
- // the list, and return it:
- move = this->pick_move_from_list();
- if(move != MOVE_NONE) {
- assert(move_is_ok(move));
- return move;
- }
-
- // Next phase:
- phaseIndex++;
- switch(PhaseTable[phaseIndex]) {
-
- case PH_TT_MOVE:
- if(ttMove != MOVE_NONE) {
- assert(move_is_ok(ttMove));
- Move m = generate_move_if_legal(*pos, ttMove, pinned);
- if(m != MOVE_NONE) {
- assert(m == ttMove);
- return m;
- }
- }
- break;
-
- case PH_MATE_KILLER:
- if(mateKiller != MOVE_NONE) {
- assert(move_is_ok(mateKiller));
- Move m = generate_move_if_legal(*pos, mateKiller, pinned);
- if(m != MOVE_NONE) {
- assert(m == mateKiller);
- return m;
- }
- }
- break;
-
- case PH_GOOD_CAPTURES:
- // pinned = pos->pinned_pieces(pos->side_to_move());
- numOfMoves = generate_captures(*pos, moves);
- this->score_captures();
- movesPicked = 0;
- break;
-
- case PH_BAD_CAPTURES:
- badCapturesPicked = 0;
- break;
-
- case PH_NONCAPTURES:
- numOfMoves = generate_noncaptures(*pos, moves);
- this->score_noncaptures();
- movesPicked = 0;
- break;
-
- case PH_EVASIONS:
- assert(pos->is_check());
- // pinned = pos->pinned_pieces(pos->side_to_move());
- numOfMoves = generate_evasions(*pos, moves);
- this->score_evasions();
- movesPicked = 0;
- break;
-
- case PH_QCAPTURES:
- // pinned = pos->pinned_pieces(pos->side_to_move());
- numOfMoves = generate_captures(*pos, moves);
- this->score_qcaptures();
- movesPicked = 0;
- break;
-
- case PH_QCHECKS:
- numOfMoves = generate_checks(*pos, moves, dc);
- movesPicked = 0;
- break;
-
- case PH_STOP:
- return MOVE_NONE;
-
- default:
- assert(false);
- return MOVE_NONE;
- }
+ // Skip TT move if is not a capture or a promotion, this avoids
+ // qsearch tree explosion due to a possible perpetual check or
+ // similar rare cases when TT table is full.
+ if (ttm != MOVE_NONE && !pos.move_is_capture(ttm) && !move_is_promotion(ttm))
+ ttm = MOVE_NONE;