- // Raise value of the picked square, so next attack
- // to the same square will get low priority.
- to = move_to(moves[bestIndex].move);
- values[to] += 0xB00;
- }
- return bestIndex;
-}
-
-
-/// MovePicker::pick_move_from_list() picks the move with the biggest score
-/// from a list of generated moves (moves[] or badCaptures[], depending on
-/// the current move generation phase). It takes care not to return the
-/// transposition table move if that has already been serched previously.
-
-Move MovePicker::pick_move_from_list() {
-
- int bestIndex;
- Move move;
-
- switch (PhaseTable[phaseIndex]) {
-
- case PH_GOOD_CAPTURES:
- assert(!pos.is_check());
- assert(movesPicked >= 0);
-
- while (movesPicked < numOfMoves)
- {
- bestIndex = find_best_index();
- move = moves[bestIndex].move;
- moves[bestIndex] = moves[movesPicked++];
- if ( move != ttMove
- && move != mateKiller
- && pos.pl_move_is_legal(move, pinned))
- return move;
- }
- break;
-
- case PH_NONCAPTURES:
- assert(!pos.is_check());
- assert(movesPicked >= 0);
-
- while (movesPicked < numOfMoves)
- {
- // If this is a PV node or we have only picked a few moves, scan
- // the entire move list for the best move. If many moves have already
- // been searched and it is not a PV node, we are probably failing low
- // anyway, so we just pick the first move from the list.
- bestIndex = (pvNode || movesPicked < 12) ? find_best_index() : movesPicked;
- move = moves[bestIndex].move;
- moves[bestIndex] = moves[movesPicked++];
- if ( move != ttMove
- && move != mateKiller
- && pos.pl_move_is_legal(move, pinned))
- return move;
- }
- break;
-
- case PH_EVASIONS:
- assert(pos.is_check());
- assert(movesPicked >= 0);
-
- while (movesPicked < numOfMoves)
- {
- bestIndex = find_best_index();
- move = moves[bestIndex].move;
- moves[bestIndex] = moves[movesPicked++];
- return move;
- }
- break;
-
- case PH_BAD_CAPTURES:
- assert(!pos.is_check());
- assert(badCapturesPicked >= 0);
- // It's probably a good idea to use SEE move ordering here, instead
- // of just picking the first move. FIXME
- while (badCapturesPicked < numOfBadCaptures)
- {
- move = badCaptures[badCapturesPicked++].move;
- if ( move != ttMove
- && move != mateKiller
- && pos.pl_move_is_legal(move, pinned))
- return move;
+ switch (phase) {
+
+ case PH_NULL_MOVE:
+ go_next_phase();
+ return MOVE_NULL;
+
+ case PH_TT_MOVES:
+ while (movesPicked < 2)
+ {
+ Move move = ttMoves[movesPicked++];
+ if ( move != MOVE_NONE
+ && move_is_legal(pos, move, pinned))
+ return move;
+ }
+ break;
+
+ case PH_GOOD_CAPTURES:
+ while (curMove != lastMove)
+ {
+ Move move = (curMove++)->move;
+ if ( move != ttMoves[0]
+ && move != ttMoves[1]
+ && pos.pl_move_is_legal(move, pinned))
+ {
+ // Check for a non negative SEE now
+ int seeValue = pos.see_sign(move);
+ if (seeValue >= 0)
+ return move;
+
+ // Losing capture, move it to the badCaptures[] array, note
+ // that move has now been already checked for legality.
+ assert(numOfBadCaptures < 63);
+ badCaptures[numOfBadCaptures].move = move;
+ badCaptures[numOfBadCaptures++].score = seeValue;
+ }
+ }
+ break;
+
+ case PH_KILLERS:
+ while (movesPicked < 2)
+ {
+ Move move = killers[movesPicked++];
+ if ( move != MOVE_NONE
+ && move != ttMoves[0]
+ && move != ttMoves[1]
+ && move_is_legal(pos, move, pinned)
+ && !pos.move_is_capture(move))
+ return move;
+ }
+ break;
+
+ case PH_NONCAPTURES:
+ while (curMove != lastMove)
+ {
+ Move move = (curMove++)->move;
+ if ( move != ttMoves[0]
+ && move != ttMoves[1]
+ && move != killers[0]
+ && move != killers[1]
+ && pos.pl_move_is_legal(move, pinned))
+ return move;
+ }
+ break;
+
+ case PH_EVASIONS:
+ case PH_BAD_CAPTURES:
+ if (curMove != lastMove)
+ return (curMove++)->move;
+ break;
+
+ case PH_QCAPTURES:
+ case PH_QCHECKS:
+ while (curMove != lastMove)
+ {
+ Move move = (curMove++)->move;
+ // Maybe postpone the legality check until after futility pruning?
+ if ( move != ttMoves[0]
+ && pos.pl_move_is_legal(move, pinned))
+ return move;
+ }
+ break;
+
+ case PH_STOP:
+ return MOVE_NONE;
+
+ default:
+ assert(false);
+ break;