X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=e6125ec7c2c756816bc098014d132fa04900ae03;hp=05e093a8a6fc8b2bae8085d1d7f0eab1806ba324;hb=9b6b9e67fe767a83837ff4cbf3954a8cf70eee59;hpb=f9f30412e798b4ba06375a383a85a9e65bfe299f diff --git a/src/position.cpp b/src/position.cpp index 05e093a8..e6125ec7 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -451,20 +451,24 @@ void Position::find_checkers() { /// computes bitboards relative to that color only, the other computes both /// colors. Bitboard checkersBB must be already updated. -void Position::find_hidden_checks(Color us) { +void Position::find_hidden_checks(Color us, unsigned int types) { Bitboard p1, p2; Color them = opposite_color(us); Square ksq = king_square(them); - st->pinned[them] = hidden_checks(them, ksq, p1) | hidden_checks(them, ksq, p2); - st->pinners[them] = p1 | p2; - st->dcCandidates[us] = hidden_checks(us, ksq, p1) | hidden_checks(us, ksq, p2); + if (types & Pinned) + { + st->pinned[them] = hidden_checks(them, ksq, p1) | hidden_checks(them, ksq, p2); + st->pinners[them] = p1 | p2; + } + if (types & DcCandidates) + st->dcCandidates[us] = hidden_checks(us, ksq, p1) | hidden_checks(us, ksq, p2); } void Position::find_hidden_checks() { for (Color c = WHITE; c <= BLACK; c++) - find_hidden_checks(c); + find_hidden_checks(c, Pinned | DcCandidates); } @@ -695,32 +699,57 @@ void Position::update_hidden_checks(Square from, Square to) { set_bit(&moveSquares, to); // Our moving piece could have been a possible pinner or hidden checker behind a dcCandidates? - bool checkerMoved = (st->dcCandidates[us] | st->pinners[them]) && (moveSquares & sliders()); + bool checkerMoved = (st->dcCandidates[us] || bit_is_set(st->pinners[them], from)) && (moveSquares & sliders()); // If we are moving from/to an opponent king attack direction and we was a possible hidden checker // or there exsist some possible hidden checker on that line then recalculate the position // otherwise skip because our dcCandidates and opponent pinned pieces are not changed. if ( (moveSquares & RookPseudoAttacks[ksq]) && (checkerMoved || (rooks_and_queens(us) & RookPseudoAttacks[ksq])) || (moveSquares & BishopPseudoAttacks[ksq]) && (checkerMoved || (bishops_and_queens(us) & BishopPseudoAttacks[ksq]))) - find_hidden_checks(us); + { + // If the move gives direct check and we don't have pinners/dc cadidates + // then we can be sure that we won't have them also after the move if + // we are not moving from a possible king attack direction. + bool outsideChecker = false; + + if ( bit_is_set(st->checkersBB, to) + && !(bit_is_set(RookPseudoAttacks[ksq], from) && (checkerMoved || (rooks_and_queens(us) & RookPseudoAttacks[ksq]))) + && !(bit_is_set(BishopPseudoAttacks[ksq], from) && (checkerMoved || (bishops_and_queens(us) & BishopPseudoAttacks[ksq])))) + outsideChecker = true; + + if (!outsideChecker || st->pinned[them]) + find_hidden_checks(us, Pinned); + + if (!outsideChecker || st->dcCandidates[us] || bit_is_set(st->pinned[them], to)) + find_hidden_checks(us, DcCandidates); + } ksq = king_square(us); if (ksq == to) { - find_hidden_checks(them); + find_hidden_checks(them, Pinned | DcCandidates); return; } // It is possible that we have captured an opponent hidden checker? - Bitboard checkerCaptured = (st->dcCandidates[them] | st->pinners[us]) && st->capture; + Bitboard checkerCaptured = st->capture && (st->dcCandidates[them] || bit_is_set(st->pinners[us], to)); // If we are moving from/to an our king attack direction and there was/is some possible // opponent hidden checker then calculate the position otherwise skip because opponent // dcCandidates and our pinned pieces are not changed. if ( (moveSquares & RookPseudoAttacks[ksq]) && (checkerCaptured || (rooks_and_queens(them) & RookPseudoAttacks[ksq])) || (moveSquares & BishopPseudoAttacks[ksq]) && (checkerCaptured || (bishops_and_queens(them) & BishopPseudoAttacks[ksq]))) - find_hidden_checks(them); + { + find_hidden_checks(them, Pinned); + + // If we don't have opponent dc candidates and we are moving in the + // attack line then won't be any dc candidates also after the move. + if ( st->dcCandidates[them] + || (bit_is_set(RookPseudoAttacks[ksq], from) && (rooks_and_queens(them) & RookPseudoAttacks[ksq])) + || (bit_is_set(BishopPseudoAttacks[ksq], from) && (bishops_and_queens(them) & BishopPseudoAttacks[ksq]))) + find_hidden_checks(them, DcCandidates); + } }