X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=65964b827a889880ca1d8322e7c339d0b81494bc;hp=67680b1fbac52c46360109abdabbd6bcf585863a;hb=7c84b39a42bfcada7e9eafd745a9616aaa8f9c1c;hpb=c02613860a3836bb85da25ae2fed9f1351ba27a5 diff --git a/src/position.cpp b/src/position.cpp index 67680b1f..65964b82 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -320,71 +320,40 @@ void Position::copy(const Position &pos) { } -/// Position:pinned_pieces() returns a bitboard of all pinned (against the -/// king) pieces for the given color. -Bitboard Position::pinned_pieces(Color c) const { - - Bitboard p; - Square ksq = king_square(c); - return hidden_checks(c, ksq, p) | hidden_checks(c, ksq, p); -} +/// Position:hidden_checkers<>() returns a bitboard of all pinned (against the +/// king) pieces for the given color and for the given pinner type. Or, when +/// template parameter FindPinned is false, the pieces of the given color +/// candidate for a discovery check against the enemy king. +/// Note that checkersBB bitboard must be already updated. +template +Bitboard Position::hidden_checkers(Color c) const { -/// Position:discovered_check_candidates() returns a bitboard containing all -/// pieces for the given side which are candidates for giving a discovered -/// check. The code is almost the same as the function for finding pinned -/// pieces. + Bitboard pinners, result = EmptyBoardBB; -Bitboard Position::discovered_check_candidates(Color c) const { + // Pinned pieces protect our king, dicovery checks attack + // the enemy king. + Square ksq = king_square(FindPinned ? c : opposite_color(c)); - Bitboard p; - Square ksq = king_square(opposite_color(c)); - return hidden_checks(c, ksq, p) | hidden_checks(c, ksq, p); -} + // Pinners are sliders, not checkers, that give check when + // candidate pinned is removed. + pinners = (rooks_and_queens(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq]) + | (bishops_and_queens(FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq]); + if (FindPinned && pinners) + pinners &= ~st->checkersBB; -/// Position:hidden_checks<>() returns a bitboard of all pinned (against the -/// king) pieces for the given color and for the given pinner type. Or, when -/// template parameter FindPinned is false, the pinned pieces of opposite color -/// that are, indeed, the pieces candidate for a discovery check. -/// Note that checkersBB bitboard must be already updated. -template -Bitboard Position::hidden_checks(Color c, Square ksq, Bitboard& pinners) const { - - Square s; - Bitboard sliders, result = EmptyBoardBB; + while (pinners) + { + Square s = pop_1st_bit(&pinners); + Bitboard b = squares_between(s, ksq) & occupied_squares(); - if (Piece == ROOK) // Resolved at compile time - sliders = rooks_and_queens(FindPinned ? opposite_color(c) : c) & RookPseudoAttacks[ksq]; - else - sliders = bishops_and_queens(FindPinned ? opposite_color(c) : c) & BishopPseudoAttacks[ksq]; + assert(b); - if (sliders && (!FindPinned || (sliders & ~st->checkersBB))) - { - // King blockers are candidate pinned pieces - Bitboard candidate_pinned = piece_attacks(ksq) & pieces_of_color(c); - - // Pinners are sliders, not checkers, that give check when - // candidate pinned are removed. - pinners = (FindPinned ? sliders & ~st->checkersBB : sliders); - - if (Piece == ROOK) - pinners &= rook_attacks_bb(ksq, occupied_squares() ^ candidate_pinned); - else - pinners &= bishop_attacks_bb(ksq, occupied_squares() ^ candidate_pinned); - - // Finally for each pinner find the corresponding pinned piece (if same color of king) - // or discovery checker (if opposite color) among the candidates. - Bitboard p = pinners; - while (p) - { - s = pop_1st_bit(&p); - result |= (squares_between(s, ksq) & candidate_pinned); - } + if ( !(b & (b - 1)) // Only one bit set? + && (b & pieces_of_color(c))) // Is an our piece? + result |= b; } - else - pinners = EmptyBoardBB; - return result; } @@ -679,7 +648,18 @@ template inline void Position::update_checkers(Bitboard* pCheckersBB, Square ksq, Square from, Square to, Bitboard dcCandidates) { - if (Piece != KING && bit_is_set(piece_attacks(ksq), to)) + const bool Bishop = (Piece == QUEEN || Piece == BISHOP); + const bool Rook = (Piece == QUEEN || Piece == ROOK); + const bool Slider = Bishop || Rook; + + if ( ( (Bishop && bit_is_set(BishopPseudoAttacks[ksq], to)) + || (Rook && bit_is_set(RookPseudoAttacks[ksq], to))) + && bit_is_set(piece_attacks(ksq), to)) // slow, try to early skip + set_bit(pCheckersBB, to); + + else if ( Piece != KING + && !Slider + && bit_is_set(piece_attacks(ksq), to)) set_bit(pCheckersBB, to); if (Piece != QUEEN && bit_is_set(dcCandidates, from)) @@ -707,10 +687,17 @@ void Position::do_move(Move m, StateInfo& newSt, Bitboard dcCandidates) { assert(is_ok()); assert(move_is_ok(m)); - // Copy some fields of old state to our new StateInfo object (except the - // captured piece, which is taken care of later) and switch state pointer - // to point to the new, ready to be updated, state. - newSt = *st; + // Copy some fields of old state to our new StateInfo object except the + // ones which are recalculated from scratch anyway, then switch our state + // pointer to point to the new, ready to be updated, state. + struct ReducedStateInfo { + Key key, pawnKey, materialKey; + int castleRights, rule50; + Square epSquare; + Value mgValue, egValue; + }; + + memcpy(&newSt, st, sizeof(ReducedStateInfo)); newSt.capture = NO_PIECE_TYPE; newSt.previous = st; st = &newSt;