mirror of
https://github.com/HChaZZY/Stockfish.git
synced 2025-12-21 01:27:16 +08:00
Move CheckInfo under StateInfo
This greately simplifies usage because hides to the search the implementation specific CheckInfo. This is based on the work done by Marco in pull request #716, implementing on top of it the ideas in the discussion: caching the calls to slider_blockers() in the CheckInfo structure, and simplifying the slider_blockers() function by removing its first parameter. Compared to master, bench is identical but the number of calls to slider_blockers() during bench goes down from 22461515 to 18853422, hopefully being a little bit faster overall. archlinux, gcc-6 make profile-build ARCH=x86-64-bmi2 50 runs each bench: base = 2356320 +/- 981 test = 2403811 +/- 981 diff = 47490 +/- 1828 speedup = 0.0202 P(speedup > 0) = 1.0000 perft 6: base = 175498484 +/- 429925 test = 183997959 +/- 429925 diff = 8499474 +/- 469401 speedup = 0.0484 P(speedup > 0) = 1.0000 perft 7 (but only 10 runs): base = 185403228 +/- 468705 test = 188777591 +/- 468705 diff = 3374363 +/- 476687 speedup = 0.0182 P(speedup > 0) = 1.0000 $ ./pyshbench ../Stockfish/master ../Stockfish/test 20 run base test diff ... base = 2501728 +/- 182034 test = 2532997 +/- 182034 diff = 31268 +/- 5116 speedup = 0.0125 P(speedup > 0) = 1.0000 No functional change.
This commit is contained in:
committed by
Marco Costalba
parent
4c5cbb1b14
commit
805afcbf3d
@@ -26,7 +26,7 @@
|
||||
namespace {
|
||||
|
||||
template<CastlingRight Cr, bool Checks, bool Chess960>
|
||||
ExtMove* generate_castling(const Position& pos, ExtMove* moveList, Color us, const CheckInfo* ci) {
|
||||
ExtMove* generate_castling(const Position& pos, ExtMove* moveList, Color us) {
|
||||
|
||||
static const bool KingSide = (Cr == WHITE_OO || Cr == BLACK_OO);
|
||||
|
||||
@@ -57,10 +57,8 @@ namespace {
|
||||
|
||||
Move m = make<CASTLING>(kfrom, rfrom);
|
||||
|
||||
if (Checks && !pos.gives_check(m, *ci))
|
||||
if (Checks && !pos.gives_check(m))
|
||||
return moveList;
|
||||
else
|
||||
(void)ci; // Silence a warning under MSVC
|
||||
|
||||
*moveList++ = m;
|
||||
return moveList;
|
||||
@@ -68,7 +66,7 @@ namespace {
|
||||
|
||||
|
||||
template<GenType Type, Square Delta>
|
||||
ExtMove* make_promotions(ExtMove* moveList, Square to, const CheckInfo* ci) {
|
||||
ExtMove* make_promotions(ExtMove* moveList, Square to, Square ksq) {
|
||||
|
||||
if (Type == CAPTURES || Type == EVASIONS || Type == NON_EVASIONS)
|
||||
*moveList++ = make<PROMOTION>(to - Delta, to, QUEEN);
|
||||
@@ -82,18 +80,15 @@ namespace {
|
||||
|
||||
// Knight promotion is the only promotion that can give a direct check
|
||||
// that's not already included in the queen promotion.
|
||||
if (Type == QUIET_CHECKS && (StepAttacksBB[W_KNIGHT][to] & ci->ksq))
|
||||
if (Type == QUIET_CHECKS && (StepAttacksBB[W_KNIGHT][to] & ksq))
|
||||
*moveList++ = make<PROMOTION>(to - Delta, to, KNIGHT);
|
||||
else
|
||||
(void)ci; // Silence a warning under MSVC
|
||||
|
||||
return moveList;
|
||||
}
|
||||
|
||||
|
||||
template<Color Us, GenType Type>
|
||||
ExtMove* generate_pawn_moves(const Position& pos, ExtMove* moveList,
|
||||
Bitboard target, const CheckInfo* ci) {
|
||||
ExtMove* generate_pawn_moves(const Position& pos, ExtMove* moveList, Bitboard target) {
|
||||
|
||||
// Compute our parametrized parameters at compile time, named according to
|
||||
// the point of view of white side.
|
||||
@@ -129,16 +124,19 @@ namespace {
|
||||
|
||||
if (Type == QUIET_CHECKS)
|
||||
{
|
||||
b1 &= pos.attacks_from<PAWN>(ci->ksq, Them);
|
||||
b2 &= pos.attacks_from<PAWN>(ci->ksq, Them);
|
||||
Square ksq = pos.square<KING>(Them);
|
||||
|
||||
b1 &= pos.attacks_from<PAWN>(ksq, Them);
|
||||
b2 &= pos.attacks_from<PAWN>(ksq, Them);
|
||||
|
||||
// Add pawn pushes which give discovered check. This is possible only
|
||||
// if the pawn is not on the same file as the enemy king, because we
|
||||
// don't generate captures. Note that a possible discovery check
|
||||
// promotion has been already generated amongst the captures.
|
||||
if (pawnsNotOn7 & ci->dcCandidates)
|
||||
Bitboard dcCandidates = pos.discovered_check_candidates();
|
||||
if (pawnsNotOn7 & dcCandidates)
|
||||
{
|
||||
Bitboard dc1 = shift_bb<Up>(pawnsNotOn7 & ci->dcCandidates) & emptySquares & ~file_bb(ci->ksq);
|
||||
Bitboard dc1 = shift_bb<Up>(pawnsNotOn7 & dcCandidates) & emptySquares & ~file_bb(ksq);
|
||||
Bitboard dc2 = shift_bb<Up>(dc1 & TRank3BB) & emptySquares;
|
||||
|
||||
b1 |= dc1;
|
||||
@@ -172,14 +170,16 @@ namespace {
|
||||
Bitboard b2 = shift_bb<Left >(pawnsOn7) & enemies;
|
||||
Bitboard b3 = shift_bb<Up >(pawnsOn7) & emptySquares;
|
||||
|
||||
Square ksq = pos.square<KING>(Them);
|
||||
|
||||
while (b1)
|
||||
moveList = make_promotions<Type, Right>(moveList, pop_lsb(&b1), ci);
|
||||
moveList = make_promotions<Type, Right>(moveList, pop_lsb(&b1), ksq);
|
||||
|
||||
while (b2)
|
||||
moveList = make_promotions<Type, Left >(moveList, pop_lsb(&b2), ci);
|
||||
moveList = make_promotions<Type, Left >(moveList, pop_lsb(&b2), ksq);
|
||||
|
||||
while (b3)
|
||||
moveList = make_promotions<Type, Up >(moveList, pop_lsb(&b3), ci);
|
||||
moveList = make_promotions<Type, Up >(moveList, pop_lsb(&b3), ksq);
|
||||
}
|
||||
|
||||
// Standard and en-passant captures
|
||||
@@ -225,7 +225,7 @@ namespace {
|
||||
|
||||
template<PieceType Pt, bool Checks>
|
||||
ExtMove* generate_moves(const Position& pos, ExtMove* moveList, Color us,
|
||||
Bitboard target, const CheckInfo* ci) {
|
||||
Bitboard target) {
|
||||
|
||||
assert(Pt != KING && Pt != PAWN);
|
||||
|
||||
@@ -236,17 +236,17 @@ namespace {
|
||||
if (Checks)
|
||||
{
|
||||
if ( (Pt == BISHOP || Pt == ROOK || Pt == QUEEN)
|
||||
&& !(PseudoAttacks[Pt][from] & target & ci->checkSquares[Pt]))
|
||||
&& !(PseudoAttacks[Pt][from] & target & pos.check_info().checkSquares[Pt]))
|
||||
continue;
|
||||
|
||||
if (ci->dcCandidates & from)
|
||||
if (pos.discovered_check_candidates() & from)
|
||||
continue;
|
||||
}
|
||||
|
||||
Bitboard b = pos.attacks_from<Pt>(from) & target;
|
||||
|
||||
if (Checks)
|
||||
b &= ci->checkSquares[Pt];
|
||||
b &= pos.check_info().checkSquares[Pt];
|
||||
|
||||
while (b)
|
||||
*moveList++ = make_move(from, pop_lsb(&b));
|
||||
@@ -257,16 +257,15 @@ namespace {
|
||||
|
||||
|
||||
template<Color Us, GenType Type>
|
||||
ExtMove* generate_all(const Position& pos, ExtMove* moveList, Bitboard target,
|
||||
const CheckInfo* ci = nullptr) {
|
||||
ExtMove* generate_all(const Position& pos, ExtMove* moveList, Bitboard target) {
|
||||
|
||||
const bool Checks = Type == QUIET_CHECKS;
|
||||
|
||||
moveList = generate_pawn_moves<Us, Type>(pos, moveList, target, ci);
|
||||
moveList = generate_moves<KNIGHT, Checks>(pos, moveList, Us, target, ci);
|
||||
moveList = generate_moves<BISHOP, Checks>(pos, moveList, Us, target, ci);
|
||||
moveList = generate_moves< ROOK, Checks>(pos, moveList, Us, target, ci);
|
||||
moveList = generate_moves< QUEEN, Checks>(pos, moveList, Us, target, ci);
|
||||
moveList = generate_pawn_moves<Us, Type>(pos, moveList, target);
|
||||
moveList = generate_moves<KNIGHT, Checks>(pos, moveList, Us, target);
|
||||
moveList = generate_moves<BISHOP, Checks>(pos, moveList, Us, target);
|
||||
moveList = generate_moves< ROOK, Checks>(pos, moveList, Us, target);
|
||||
moveList = generate_moves< QUEEN, Checks>(pos, moveList, Us, target);
|
||||
|
||||
if (Type != QUIET_CHECKS && Type != EVASIONS)
|
||||
{
|
||||
@@ -280,13 +279,13 @@ namespace {
|
||||
{
|
||||
if (pos.is_chess960())
|
||||
{
|
||||
moveList = generate_castling<MakeCastling<Us, KING_SIDE>::right, Checks, true>(pos, moveList, Us, ci);
|
||||
moveList = generate_castling<MakeCastling<Us, QUEEN_SIDE>::right, Checks, true>(pos, moveList, Us, ci);
|
||||
moveList = generate_castling<MakeCastling<Us, KING_SIDE>::right, Checks, true>(pos, moveList, Us);
|
||||
moveList = generate_castling<MakeCastling<Us, QUEEN_SIDE>::right, Checks, true>(pos, moveList, Us);
|
||||
}
|
||||
else
|
||||
{
|
||||
moveList = generate_castling<MakeCastling<Us, KING_SIDE>::right, Checks, false>(pos, moveList, Us, ci);
|
||||
moveList = generate_castling<MakeCastling<Us, QUEEN_SIDE>::right, Checks, false>(pos, moveList, Us, ci);
|
||||
moveList = generate_castling<MakeCastling<Us, KING_SIDE>::right, Checks, false>(pos, moveList, Us);
|
||||
moveList = generate_castling<MakeCastling<Us, QUEEN_SIDE>::right, Checks, false>(pos, moveList, Us);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,8 +334,7 @@ ExtMove* generate<QUIET_CHECKS>(const Position& pos, ExtMove* moveList) {
|
||||
assert(!pos.checkers());
|
||||
|
||||
Color us = pos.side_to_move();
|
||||
CheckInfo ci(pos);
|
||||
Bitboard dc = ci.dcCandidates;
|
||||
Bitboard dc = pos.discovered_check_candidates();
|
||||
|
||||
while (dc)
|
||||
{
|
||||
@@ -349,14 +347,14 @@ ExtMove* generate<QUIET_CHECKS>(const Position& pos, ExtMove* moveList) {
|
||||
Bitboard b = pos.attacks_from(Piece(pt), from) & ~pos.pieces();
|
||||
|
||||
if (pt == KING)
|
||||
b &= ~PseudoAttacks[QUEEN][ci.ksq];
|
||||
b &= ~PseudoAttacks[QUEEN][pos.square<KING>(~us)];
|
||||
|
||||
while (b)
|
||||
*moveList++ = make_move(from, pop_lsb(&b));
|
||||
}
|
||||
|
||||
return us == WHITE ? generate_all<WHITE, QUIET_CHECKS>(pos, moveList, ~pos.pieces(), &ci)
|
||||
: generate_all<BLACK, QUIET_CHECKS>(pos, moveList, ~pos.pieces(), &ci);
|
||||
return us == WHITE ? generate_all<WHITE, QUIET_CHECKS>(pos, moveList, ~pos.pieces())
|
||||
: generate_all<BLACK, QUIET_CHECKS>(pos, moveList, ~pos.pieces());
|
||||
}
|
||||
|
||||
|
||||
@@ -411,7 +409,7 @@ ExtMove* generate<LEGAL>(const Position& pos, ExtMove* moveList) {
|
||||
: generate<NON_EVASIONS>(pos, moveList);
|
||||
while (cur != moveList)
|
||||
if ( (pinned || from_sq(*cur) == ksq || type_of(*cur) == ENPASSANT)
|
||||
&& !pos.legal(*cur, pinned))
|
||||
&& !pos.legal(*cur))
|
||||
*cur = (--moveList)->move;
|
||||
else
|
||||
++cur;
|
||||
|
||||
Reference in New Issue
Block a user