1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-04-29 16:23:09 +00:00

Remove QS_CHECKS movepick stage

Passed STC: https://tests.stockfishchess.org/tests/view/669597cf4ff211be9d4ec147
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 199072 W: 52100 L: 52058 D: 94914
Ptnml(0-2): 829, 23679, 50406, 23865, 757

Passed LTC: https://tests.stockfishchess.org/tests/view/66988f5f4ff211be9d4ec33e
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 119778 W: 30420 L: 30299 D: 59059
Ptnml(0-2): 106, 13293, 32957, 13440, 93

closes https://github.com/official-stockfish/Stockfish/pull/5498

Bench 1499842
This commit is contained in:
Dubslow 2024-05-02 05:35:15 -05:00 committed by Joost VandeVondele
parent e57fba7fc9
commit 703f17975b
5 changed files with 19 additions and 71 deletions

View file

@ -75,17 +75,6 @@ ExtMove* generate_pawn_moves(const Position& pos, ExtMove* moveList, Bitboard ta
b2 &= target;
}
if constexpr (Type == QUIET_CHECKS)
{
// To make a quiet check, you either make a direct check by pushing a pawn
// or push a blocker pawn that is not on the same file as the enemy king.
// Discovered check promotion has been already generated amongst the captures.
Square ksq = pos.square<KING>(Them);
Bitboard dcCandidatePawns = pos.blockers_for_king(Them) & ~file_bb(ksq);
b1 &= pawn_attacks_bb(Them, ksq) | shift<Up>(dcCandidatePawns);
b2 &= pawn_attacks_bb(Them, ksq) | shift<Up + Up>(dcCandidatePawns);
}
while (b1)
{
Square to = pop_lsb(b1);
@ -158,7 +147,7 @@ ExtMove* generate_pawn_moves(const Position& pos, ExtMove* moveList, Bitboard ta
}
template<Color Us, PieceType Pt, bool Checks>
template<Color Us, PieceType Pt>
ExtMove* generate_moves(const Position& pos, ExtMove* moveList, Bitboard target) {
static_assert(Pt != KING && Pt != PAWN, "Unsupported piece type in generate_moves()");
@ -170,10 +159,6 @@ ExtMove* generate_moves(const Position& pos, ExtMove* moveList, Bitboard target)
Square from = pop_lsb(bb);
Bitboard b = attacks_bb<Pt>(from, pos.pieces()) & target;
// To check, you either move freely a blocker or make a direct check.
if (Checks && (Pt == QUEEN || !(pos.blockers_for_king(~Us) & from)))
b &= pos.check_squares(Pt);
while (b)
*moveList++ = Move(from, pop_lsb(b));
}
@ -187,9 +172,8 @@ ExtMove* generate_all(const Position& pos, ExtMove* moveList) {
static_assert(Type != LEGAL, "Unsupported type in generate_all()");
constexpr bool Checks = Type == QUIET_CHECKS; // Reduce template instantiations
const Square ksq = pos.square<KING>(Us);
Bitboard target;
const Square ksq = pos.square<KING>(Us);
Bitboard target;
// Skip generating non-king moves when in double check
if (Type != EVASIONS || !more_than_one(pos.checkers()))
@ -197,29 +181,24 @@ ExtMove* generate_all(const Position& pos, ExtMove* moveList) {
target = Type == EVASIONS ? between_bb(ksq, lsb(pos.checkers()))
: Type == NON_EVASIONS ? ~pos.pieces(Us)
: Type == CAPTURES ? pos.pieces(~Us)
: ~pos.pieces(); // QUIETS || QUIET_CHECKS
: ~pos.pieces(); // QUIETS
moveList = generate_pawn_moves<Us, Type>(pos, moveList, target);
moveList = generate_moves<Us, KNIGHT, Checks>(pos, moveList, target);
moveList = generate_moves<Us, BISHOP, Checks>(pos, moveList, target);
moveList = generate_moves<Us, ROOK, Checks>(pos, moveList, target);
moveList = generate_moves<Us, QUEEN, Checks>(pos, moveList, target);
moveList = generate_moves<Us, KNIGHT>(pos, moveList, target);
moveList = generate_moves<Us, BISHOP>(pos, moveList, target);
moveList = generate_moves<Us, ROOK>(pos, moveList, target);
moveList = generate_moves<Us, QUEEN>(pos, moveList, target);
}
if (!Checks || pos.blockers_for_king(~Us) & ksq)
{
Bitboard b = attacks_bb<KING>(ksq) & (Type == EVASIONS ? ~pos.pieces(Us) : target);
if (Checks)
b &= ~attacks_bb<QUEEN>(pos.square<KING>(~Us));
Bitboard b = attacks_bb<KING>(ksq) & (Type == EVASIONS ? ~pos.pieces(Us) : target);
while (b)
*moveList++ = Move(ksq, pop_lsb(b));
while (b)
*moveList++ = Move(ksq, pop_lsb(b));
if ((Type == QUIETS || Type == NON_EVASIONS) && pos.can_castle(Us & ANY_CASTLING))
for (CastlingRights cr : {Us & KING_SIDE, Us & QUEEN_SIDE})
if (!pos.castling_impeded(cr) && pos.can_castle(cr))
*moveList++ = Move::make<CASTLING>(ksq, pos.castling_rook_square(cr));
}
if ((Type == QUIETS || Type == NON_EVASIONS) && pos.can_castle(Us & ANY_CASTLING))
for (CastlingRights cr : {Us & KING_SIDE, Us & QUEEN_SIDE})
if (!pos.castling_impeded(cr) && pos.can_castle(cr))
*moveList++ = Move::make<CASTLING>(ksq, pos.castling_rook_square(cr));
return moveList;
}
@ -231,8 +210,6 @@ ExtMove* generate_all(const Position& pos, ExtMove* moveList) {
// <QUIETS> Generates all pseudo-legal non-captures and underpromotions
// <EVASIONS> Generates all pseudo-legal check evasions
// <NON_EVASIONS> Generates all pseudo-legal captures and non-captures
// <QUIET_CHECKS> Generates all pseudo-legal non-captures giving check,
// except castling and promotions
//
// Returns a pointer to the end of the move list.
template<GenType Type>
@ -251,7 +228,6 @@ ExtMove* generate(const Position& pos, ExtMove* moveList) {
template ExtMove* generate<CAPTURES>(const Position&, ExtMove*);
template ExtMove* generate<QUIETS>(const Position&, ExtMove*);
template ExtMove* generate<EVASIONS>(const Position&, ExtMove*);
template ExtMove* generate<QUIET_CHECKS>(const Position&, ExtMove*);
template ExtMove* generate<NON_EVASIONS>(const Position&, ExtMove*);

View file

@ -31,7 +31,6 @@ class Position;
enum GenType {
CAPTURES,
QUIETS,
QUIET_CHECKS,
EVASIONS,
NON_EVASIONS,
LEGAL

View file

@ -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.
@ -316,24 +314,6 @@ top:
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; });
}

View file

@ -1475,12 +1475,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);
@ -1491,7 +1485,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;
@ -1674,7 +1668,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);

View file

@ -194,8 +194,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