Square rfrom = pos.castling_rook_square(Cr);
Square kto = make_square(KingSide ? pos.castling_kingside_file() : pos.castling_queenside_file(),
relative_rank(us, RANK_1, pos.max_rank()));
- Bitboard enemies = pos.pieces(~us);
assert(!pos.checkers());
if (type_of(pos.piece_on(kfrom)) == KING)
{
for (Square s = kto; s != kfrom; s += step)
- if (pos.attackers_to(s) & enemies)
+ if (pos.attackers_to(s, ~us))
return moveList;
// Because we generate only legal castling moves we need to verify that
// when moving the castling rook we do not discover some hidden checker.
// For instance an enemy queen in SQ_A1 when castling rook is in SQ_B1.
- if (Chess960 && (pos.attackers_to(kto, pos.pieces() ^ rfrom) & pos.pieces(~us)))
+ if (Chess960 && pos.attackers_to(kto, pos.pieces() ^ rfrom, ~us))
return moveList;
}
si->pawnKey = Zobrist::noPawns;
si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO;
si->psq = SCORE_ZERO;
- si->checkersBB = count<KING>(sideToMove) ? attackers_to(square<KING>(sideToMove)) & pieces(~sideToMove) : 0;
+ si->checkersBB = count<KING>(sideToMove) ? attackers_to(square<KING>(sideToMove), ~sideToMove) : 0;
set_check_info(si);
/// Position::attackers_to() computes a bitboard of all pieces which attack a
/// given square. Slider attacks use the occupied bitboard to indicate occupancy.
-Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
+Bitboard Position::attackers_to(Square s, Bitboard occupied, Color c) const {
Bitboard b = 0;
- for (Color c = WHITE; c <= BLACK; ++c)
- for (PieceType pt : piece_types())
- b |= attacks_bb(~c, pt, s, occupied) & pieces(c, pt);
+ for (PieceType pt : piece_types())
+ b |= attacks_bb(~c, pt, s, occupied) & pieces(c, pt);
return b;
}
+Bitboard Position::attackers_to(Square s, Bitboard occupied) const {
+ return attackers_to(s, occupied, WHITE) | attackers_to(s, occupied, BLACK);
+}
+
+
/// Position::legal() tests whether a pseudo-legal move is legal
bool Position::legal(Move m) const {
assert(piece_on(capsq) == make_piece(~us, PAWN));
assert(piece_on(to) == NO_PIECE);
- return !count<KING>(us) || !(attackers_to(ksq, occupied) & pieces(~us) & occupied);
+ return !count<KING>(us) || !(attackers_to(ksq, occupied, ~us) & occupied);
}
// If the moving piece is a king, check whether the destination
// square is attacked by the opponent. Castling moves are checked
// for legality during move generation.
if (type_of(moved_piece(m)) == KING)
- return type_of(m) == CASTLING || !(attackers_to(to) & pieces(~us));
+ return type_of(m) == CASTLING || !attackers_to(to, ~us);
// A non-king move is legal if the king is not under attack after the move.
- return !count<KING>(us) || !( attackers_to(ksq, (type_of(m) != DROP ? pieces() ^ from : pieces()) | to)
- & pieces(~us) & ~SquareBB[to]);
+ return !count<KING>(us) || !(attackers_to(ksq, (type_of(m) != DROP ? pieces() ^ from : pieces()) | to, ~us) & ~SquareBB[to]);
}
}
// In case of king moves under check we have to remove king so as to catch
// invalid moves like b1a1 when opposite queen is on c1.
- else if (attackers_to(to, pieces() ^ from) & pieces(~us))
+ else if (attackers_to(to, pieces() ^ from, ~us))
return false;
}
// Is there a discovered check?
if ( type_of(m) != DROP
&& (st->blockersForKing[~sideToMove] & from)
- && (attackers_to(square<KING>(~sideToMove), (pieces() ^ from) | to) & pieces(sideToMove)))
+ && attackers_to(square<KING>(~sideToMove), (pieces() ^ from) | to, sideToMove))
return true;
switch (type_of(m))
// Attacks to/from a given square
Bitboard attackers_to(Square s) const;
+ Bitboard attackers_to(Square s, Color c) const;
Bitboard attackers_to(Square s, Bitboard occupied) const;
+ Bitboard attackers_to(Square s, Bitboard occupied, Color c) const;
Bitboard attacks_from(Color c, PieceType pt, Square s) const;
template<PieceType> Bitboard attacks_from(Color c, Square s) const;
Bitboard moves_from(Color c, PieceType pt, Square s) const;
return attackers_to(s, byTypeBB[ALL_PIECES]);
}
+inline Bitboard Position::attackers_to(Square s, Color c) const {
+ return attackers_to(s, byTypeBB[ALL_PIECES], c);
+}
+
inline Bitboard Position::checkers() const {
return st->checkersBB;
}