MAIN_SEARCH, CAPTURES_INIT, GOOD_CAPTURES, KILLER0, KILLER1, COUNTERMOVE, QUIET_INIT, QUIET, BAD_CAPTURES,
EVASION, EVASIONS_INIT, ALL_EVASIONS,
PROBCUT, PROBCUT_CAPTURES_INIT, PROBCUT_CAPTURES,
- QSEARCH, QCAPTURES_INIT, QCAPTURES, QCHECKS, QSEARCH_RECAPTURES, QRECAPTURES
+ QSEARCH, QCAPTURES_INIT, QCAPTURES, QCHECKS
};
// partial_insertion_sort() sorts moves in descending order up to and including
/// MovePicker constructor for the main search
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh,
const CapturePieceToHistory* cph, const PieceToHistory** ch, Move cm, Move* killers_p)
- : pos(p), mainHistory(mh), captureHistory(cph), contHistory(ch), countermove(cm),
- killers{killers_p[0], killers_p[1]}, depth(d){
+ : pos(p), mainHistory(mh), captureHistory(cph), contHistory(ch),
+ refutations{killers_p[0], killers_p[1], cm}, depth(d){
assert(d > DEPTH_ZERO);
/// MovePicker constructor for quiescence search
MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const ButterflyHistory* mh, const CapturePieceToHistory* cph, Square s)
- : pos(p), mainHistory(mh), captureHistory(cph), depth(d) {
+ : pos(p), mainHistory(mh), captureHistory(cph), recaptureSquare(s), depth(d) {
assert(d <= DEPTH_ZERO);
- if (pos.checkers())
- stage = EVASION;
-
- else if (d > DEPTH_QS_RECAPTURES)
- stage = QSEARCH;
-
- else
- {
- stage = QSEARCH_RECAPTURES;
- recaptureSquare = s;
- return;
- }
-
- ttMove = ttm && pos.pseudo_legal(ttm) ? ttm : MOVE_NONE;
+ stage = pos.checkers() ? EVASION : QSEARCH;
+ ttMove = ttm
+ && pos.pseudo_legal(ttm)
+ && (depth > DEPTH_QS_RECAPTURES || to_sq(ttm) == recaptureSquare) ? ttm : MOVE_NONE;
stage += (ttMove == MOVE_NONE);
}
&& pos.pseudo_legal(ttm)
&& pos.capture(ttm)
&& pos.see_ge(ttm, threshold) ? ttm : MOVE_NONE;
-
stage += (ttMove == MOVE_NONE);
}
Move move;
+begin_switch:
+
switch (stage) {
- case MAIN_SEARCH: case EVASION: case QSEARCH: case PROBCUT:
+ case MAIN_SEARCH:
+ case EVASION:
+ case QSEARCH:
+ case PROBCUT:
++stage;
return ttMove;
case CAPTURES_INIT:
case PROBCUT_CAPTURES_INIT:
case QCAPTURES_INIT:
- case QSEARCH_RECAPTURES:
endBadCaptures = cur = moves;
endMoves = generate<CAPTURES>(pos, cur);
score<CAPTURES>();
++stage;
- // Rebranch at the top of the switch via a recursive call
- return next_move(skipQuiets);
+ // Rebranch at the top of the switch
+ goto begin_switch;
case GOOD_CAPTURES:
while (cur < endMoves)
}
}
++stage;
+
+ // If the countermove is the same as a killer, skip it
+ if ( refutations[0] == refutations[2]
+ || refutations[1] == refutations[2])
+ refutations[2] = MOVE_NONE;
+
/* fallthrough */
case KILLER0:
case KILLER1:
- do
+ case COUNTERMOVE:
+ while (stage <= COUNTERMOVE)
{
- move = killers[++stage - KILLER1];
+ move = refutations[ stage++ - KILLER0 ];
if ( move != MOVE_NONE
&& move != ttMove
&& pos.pseudo_legal(move)
&& !pos.capture(move))
return move;
- } while (stage <= KILLER1);
- /* fallthrough */
-
- case COUNTERMOVE:
- ++stage;
- move = countermove;
- if ( move != MOVE_NONE
- && move != ttMove
- && move != killers[0]
- && move != killers[1]
- && pos.pseudo_legal(move)
- && !pos.capture(move))
- return move;
+ }
/* fallthrough */
case QUIET_INIT:
case QUIET:
if (!skipQuiets)
- while (cur < endMoves)
- {
- move = *cur++;
-
- if ( move != ttMove
- && move != killers[0]
- && move != killers[1]
- && move != countermove)
- return move;
- }
+ while (cur < endMoves)
+ {
+ move = *cur++;
+ if ( move != ttMove
+ && move != refutations[0]
+ && move != refutations[1]
+ && move != refutations[2])
+ return move;
+ }
++stage;
cur = moves; // Point to beginning of bad captures
/* fallthrough */
while (cur < endMoves)
{
move = pick_best(cur++, endMoves);
- if (move != ttMove)
+ if ( move != ttMove
+ && (depth > DEPTH_QS_RECAPTURES || to_sq(move) == recaptureSquare))
return move;
}
if (depth <= DEPTH_QS_NO_CHECKS)
/* fallthrough */
case QCHECKS:
- while (cur < endMoves)
- {
- move = cur++->move;
- if (move != ttMove)
- return move;
- }
- break;
-
- case QRECAPTURES:
while (cur < endMoves)
{
move = *cur++;
- if (to_sq(move) == recaptureSquare)
+ if (move != ttMove)
return move;
}
break;