}
+/// Position:pinned_pieces() returns a bitboard of all pinned (against the
+/// king) pieces for the given color.
+
+Bitboard Position::pinned_pieces(Color c) const {
+
+ return hidden_checkers<true>(c);
+}
+
+
+/// Position:discovered_check_candidates() returns a bitboard containing all
+/// pieces for the given side which are candidates for giving a discovered
+/// check.
+
+Bitboard Position::discovered_check_candidates(Color c) const {
+
+ return hidden_checkers<false>(c);
+}
+
/// Position::attacks_to() computes a bitboard containing all pieces which
/// attacks a given square. There are two versions of this function: One
/// which finds attackers of both colors, and one which only finds the
inline void Position::update_checkers(Bitboard* pCheckersBB, Square ksq, Square from,
Square to, Bitboard dcCandidates) {
- if (Piece != KING && bit_is_set(piece_attacks<Piece>(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<Piece>(ksq), to)) // slow, try to early skip
+ set_bit(pCheckersBB, to);
+
+ else if ( Piece != KING
+ && !Slider
+ && bit_is_set(piece_attacks<Piece>(ksq), to))
set_bit(pCheckersBB, to);
if (Piece != QUEEN && bit_is_set(dcCandidates, from))
board[to] = EMPTY;
}
- // Finally point out state pointer back to the previous state
+ // Finally point our state pointer back to the previous state
st = st->previous;
assert(is_ok());
/// Position::do_null_move makes() a "null move": It switches the side to move
/// and updates the hash key without executing any move on the board.
-void Position::do_null_move(StateInfo& newSt) {
+void Position::do_null_move(StateInfo& backupSt) {
assert(is_ok());
assert(!is_check());
// Back up the information necessary to undo the null move to the supplied
// StateInfo object. In the case of a null move, the only thing we need to
// remember is the last move made and the en passant square.
- newSt.lastMove = st->lastMove;
- newSt.epSquare = st->epSquare;
- newSt.previous = st->previous;
- st->previous = &newSt;
+ // Note that differently from normal case here backupSt is actually used as
+ // a backup storage not as a new state to be used.
+ backupSt.lastMove = st->lastMove;
+ backupSt.epSquare = st->epSquare;
+ backupSt.previous = st->previous;
+ st->previous = &backupSt;
// Save the current key to the history[] array, in order to be able to
// detect repetition draws.
assert(is_ok());
assert(!is_check());
- // Restore information from the our StateInfo object
+ // Restore information from the our backup StateInfo object
st->lastMove = st->previous->lastMove;
st->epSquare = st->previous->epSquare;
st->previous = st->previous->previous;