Skip to content

Commit

Permalink
Remove QS_CHECKS movepick stage
Browse files Browse the repository at this point in the history
I've tried this a few times in the last half a year, it had been stubbornly worth 1 elo. However, other recent movepick simplifs seem to have cleared the way for this: simplifications beget simplifications.

I assume that, like most other search/movepick simplifications in the last two years, this is a result of the NNUE eval. NNUE seems to make obsolete all the best search tweaks!
  • Loading branch information
PikaCat-OuO committed Jul 20, 2024
1 parent 4c7d431 commit 5df62a6
Show file tree
Hide file tree
Showing 5 changed files with 7 additions and 45 deletions.
16 changes: 3 additions & 13 deletions src/movegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ ExtMove* generate_moves(const Position& pos, ExtMove* moveList, Bitboard target)
else
{
// Generate cannon capture moves.
if (Type != QUIETS && Type != QUIET_CHECKS)
if (Type != QUIETS)
b |= attacks_bb<CANNON>(from, pos.pieces()) & pos.pieces(~Us);

// Generate cannon quite moves.
Expand All @@ -56,12 +56,6 @@ ExtMove* generate_moves(const Position& pos, ExtMove* moveList, Bitboard target)
b &= target;
}

// To check, you either move freely a blocker or make a direct check.
if constexpr (Type == QUIET_CHECKS)
b &= Pt == CANNON ? ~line_bb(from, pos.king_square(~Us)) & pos.check_squares(Pt)
: (pos.blockers_for_king(~Us) & from) ? ~line_bb(from, pos.king_square(~Us))
: pos.check_squares(Pt);

while (b)
*moveList++ = Move(from, pop_lsb(b));
}
Expand All @@ -86,15 +80,13 @@ ExtMove* generate_all(const Position& pos, ExtMove* moveList) {
const Square ksq = pos.king_square(Us);
Bitboard target = Type == PSEUDO_LEGAL ? ~pos.pieces(Us)
: Type == CAPTURES ? pos.pieces(~Us)
: ~pos.pieces(); // QUIETS || QUIET_CHECKS
: ~pos.pieces(); // QUIETS

moveList = generate_moves<Us, Type>(pos, moveList, target);

if (Type != EVASIONS && (Type != QUIET_CHECKS || pos.blockers_for_king(~Us) & ksq))
if (Type != EVASIONS)
{
Bitboard b = attacks_bb<KING>(ksq) & target;
if constexpr (Type == QUIET_CHECKS)
b &= ~attacks_bb<ROOK>(pos.king_square(~Us));

while (b)
*moveList++ = Move(ksq, pop_lsb(b));
Expand All @@ -109,7 +101,6 @@ ExtMove* generate_all(const Position& pos, ExtMove* moveList) {
// <CAPTURES> Generates all pseudo-legal captures
// <QUIETS> Generates all pseudo-legal non-captures
// <PSEUDO_LEGAL> Generates all pseudo-legal captures and non-captures
// <QUIET_CHECKS> Generates all pseudo-legal non-captures giving check
//
// Returns a pointer to the end of the move list.
template<GenType Type>
Expand All @@ -124,7 +115,6 @@ ExtMove* generate(const Position& pos, ExtMove* moveList) {
// Explicit template instantiations
template ExtMove* generate<CAPTURES>(const Position&, ExtMove*);
template ExtMove* generate<QUIETS>(const Position&, ExtMove*);
template ExtMove* generate<QUIET_CHECKS>(const Position&, ExtMove*);
template ExtMove* generate<PSEUDO_LEGAL>(const Position&, ExtMove*);


Expand Down
1 change: 0 additions & 1 deletion src/movegen.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ class Position;
enum GenType {
CAPTURES,
QUIETS,
QUIET_CHECKS,
EVASIONS,
PSEUDO_LEGAL,
LEGAL
Expand Down
22 changes: 1 addition & 21 deletions src/movepick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,7 @@ enum Stages {
// generate qsearch moves
QSEARCH_TT,
QCAPTURE_INIT,
QCAPTURE,
QCHECK_INIT,
QCHECK
QCAPTURE
};

// Sort moves in descending order up to and including a given limit.
Expand Down Expand Up @@ -323,24 +321,6 @@ Move MovePicker::next_move(bool skipQuiets) {
return select<Next>([&]() { return pos.see_ge(*cur, threshold); });

case QCAPTURE :
if (select<Next>([]() { return true; }))
return *(cur - 1);

// If we found no move and the depth is too low to try checks, then we have finished
if (depth <= DEPTH_QS_NORMAL)
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; });
}

Expand Down
10 changes: 2 additions & 8 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1369,12 +1369,6 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,

assert(0 <= ss->ply && ss->ply < MAX_PLY);

// Note that unlike regular search, which stores the literal depth into the
// transposition table, from qsearch we only store the current movegen stage
// as "depth". If in check, we search all evasions and thus store DEPTH_QS_CHECKS.
// Evasions may be quiet, and _CHECKS includes quiets.
Depth qsTtDepth = ss->inCheck || depth >= DEPTH_QS_CHECKS ? DEPTH_QS_CHECKS : DEPTH_QS_NORMAL;

// Step 3. Transposition table lookup
posKey = pos.key();
auto [ttHit, ttData, ttWriter] = tt.probe(posKey);
Expand All @@ -1385,7 +1379,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,
pvHit = ttHit && ttData.is_pv;

// At non-PV nodes we check for an early TT cutoff
if (!PvNode && ttData.depth >= qsTtDepth
if (!PvNode && ttData.depth >= DEPTH_QS
&& ttData.value != VALUE_NONE // Can happen when !ttHit or when access race in probe()
&& (ttData.bound & (ttData.value >= beta ? BOUND_LOWER : BOUND_UPPER)))
return ttData.value;
Expand Down Expand Up @@ -1567,7 +1561,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta,
// Save gathered info in transposition table. The static evaluation
// is saved as it was before adjustment by correction history.
ttWriter.write(posKey, value_to_tt(bestValue, ss->ply), pvHit,
bestValue >= beta ? BOUND_LOWER : BOUND_UPPER, qsTtDepth, bestMove,
bestValue >= beta ? BOUND_LOWER : BOUND_UPPER, DEPTH_QS, bestMove,
unadjustedStaticEval, tt.generation());

assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
Expand Down
3 changes: 1 addition & 2 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ enum : int {
// quiescence search, however, the transposition table entries only store
// the current quiescence move generation stage (which should thus compare
// lower than any regular search depth).
DEPTH_QS_CHECKS = 0,
DEPTH_QS_NORMAL = -1,
DEPTH_QS = 0,
// For transposition table entries where no searching at all was done
// (whether regular or qsearch) we use DEPTH_UNSEARCHED, which should thus
// compare lower than any quiescence or regular depth. DEPTH_ENTRY_OFFSET
Expand Down

0 comments on commit 5df62a6

Please sign in to comment.