PH_BAD_CAPTURES, // Queen promotions and captures with SEE values < captureThreshold (captureThreshold <= 0)
PH_EVASIONS, // Check evasions
PH_QCAPTURES, // Captures in quiescence search
+ PH_QRECAPTURES, // Recaptures in quiescence search
PH_QCHECKS, // Non-capture checks in quiescence search
PH_STOP
};
const uint8_t EvasionTable[] = { PH_TT_MOVE, PH_EVASIONS, PH_STOP };
const uint8_t QsearchWithChecksTable[] = { PH_TT_MOVE, PH_QCAPTURES, PH_QCHECKS, PH_STOP };
const uint8_t QsearchWithoutChecksTable[] = { PH_TT_MOVE, PH_QCAPTURES, PH_STOP };
+ const uint8_t QsearchRecapturesTable[] = { PH_TT_MOVE, PH_QRECAPTURES, PH_STOP };
const uint8_t ProbCutTable[] = { PH_TT_MOVE, PH_GOOD_PROBCUT, PH_STOP };
}
go_next_phase();
}
-MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const History& h)
+MovePicker::MovePicker(const Position& p, Move ttm, Depth d, const History& h, Square recaptureSq)
: pos(p), H(h) {
assert(d <= DEPTH_ZERO);
phasePtr = EvasionTable;
else if (d >= DEPTH_QS_CHECKS)
phasePtr = QsearchWithChecksTable;
- else
+ else if (d >= DEPTH_QS_RECAPTURES)
{
phasePtr = QsearchWithoutChecksTable;
// 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))
+ if (ttm != MOVE_NONE && !pos.move_is_capture_or_promotion(ttm))
ttm = MOVE_NONE;
}
+ else
+ {
+ phasePtr = QsearchRecapturesTable;
+ recaptureSquare = recaptureSq;
+ ttm = MOVE_NONE;
+ }
ttMove = (ttm && pos.move_is_pl(ttm) ? ttm : MOVE_NONE);
phasePtr += int(ttMove == MOVE_NONE) - 1;
go_next_phase();
}
-MovePicker::MovePicker(const Position& p, Move ttm, const History& h, int threshold)
+MovePicker::MovePicker(const Position& p, Move ttm, const History& h, PieceType parentCapture)
: pos(p), H(h) {
assert (!pos.in_check());
// In ProbCut we consider only captures better than parent's move
- captureThreshold = threshold;
+ captureThreshold = piece_value_midgame(Piece(parentCapture));
phasePtr = ProbCutTable;
if ( ttm != MOVE_NONE
score_captures();
return;
+ case PH_QRECAPTURES:
+ lastMove = generate<MV_CAPTURE>(pos, moves);
+ return;
+
case PH_QCHECKS:
lastMove = generate<MV_NON_CAPTURE_CHECK>(pos, moves);
return;
for (MoveStack* cur = moves; cur != lastMove; cur++)
{
m = cur->move;
+ cur->score = piece_value_midgame(pos.piece_on(move_to(m)))
+ - pos.type_of_piece_on(move_from(m));
+
if (move_is_promotion(m))
- cur->score = QueenValueMidgame;
- else
- cur->score = pos.midgame_value_of_piece_on(move_to(m))
- - pos.type_of_piece_on(move_from(m));
+ cur->score += QueenValueMidgame;
}
}
if ((seeScore = pos.see_sign(m)) < 0)
cur->score = seeScore - History::MaxValue; // Be sure we are at the bottom
else if (pos.move_is_capture(m))
- cur->score = pos.midgame_value_of_piece_on(move_to(m))
+ cur->score = piece_value_midgame(pos.piece_on(move_to(m)))
- pos.type_of_piece_on(move_from(m)) + History::MaxValue;
else
cur->score = H.value(pos.piece_on(move_from(m)), move_to(m));
return move;
break;
+ case PH_QRECAPTURES:
+ move = (curMove++)->move;
+ if (move_to(move) == recaptureSquare)
+ return move;
+ break;
+
case PH_QCHECKS:
move = (curMove++)->move;
if (move != ttMove)