CheckInfo::CheckInfo(const Position& pos) {
- Color us = pos.side_to_move();
- Color them = opposite_color(us);
+ Color them = opposite_color(pos.side_to_move());
Square ksq = pos.king_square(them);
- dcCandidates = pos.discovered_check_candidates(us);
- pinned = pos.pinned_pieces(us);
+ pinned = pos.pinned_pieces();
+ dcCandidates = pos.discovered_check_candidates();
checkSq[PAWN] = pos.attacks_from<PAWN>(ksq, them);
checkSq[KNIGHT] = pos.attacks_from<KNIGHT>(ksq);
detach(); // Always detach() in copy c'tor to avoid surprises
threadID = th;
nodes = 0;
+
+ assert(is_ok());
}
Position::Position(const string& fen, bool isChess960, int th) {
st->value = compute_value();
st->npMaterial[WHITE] = compute_non_pawn_material(WHITE);
st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
+
+ assert(is_ok());
}
/// 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.
-/// Bitboard checkersBB must be already updated when looking for pinners.
+/// king) pieces for the given color. Or, when template parameter FindPinned is
+/// false, the function return the pieces of the given color candidate for a
+/// discovery check against the enemy king.
template<bool FindPinned>
-Bitboard Position::hidden_checkers(Color c) const {
-
- Bitboard result = EmptyBoardBB;
- Bitboard pinners = pieces(FindPinned ? opposite_color(c) : c);
+Bitboard Position::hidden_checkers() const {
- // Pinned pieces protect our king, dicovery checks attack
- // the enemy king.
- Square ksq = king_square(FindPinned ? c : opposite_color(c));
+ // Pinned pieces protect our king, dicovery checks attack the enemy king
+ Bitboard b, result = EmptyBoardBB;
+ Bitboard pinners = pieces(FindPinned ? opposite_color(sideToMove) : sideToMove);
+ Square ksq = king_square(FindPinned ? sideToMove : opposite_color(sideToMove));
- // Pinners are sliders, not checkers, that give check when candidate pinned is removed
- pinners &= (pieces(ROOK, QUEEN) & RookPseudoAttacks[ksq]) | (pieces(BISHOP, QUEEN) & BishopPseudoAttacks[ksq]);
-
- if (FindPinned && pinners)
- pinners &= ~st->checkersBB;
+ // Pinners are sliders, that give check when candidate pinned is removed
+ pinners &= (pieces(ROOK, QUEEN) & RookPseudoAttacks[ksq])
+ | (pieces(BISHOP, QUEEN) & BishopPseudoAttacks[ksq]);
while (pinners)
{
- Square s = pop_1st_bit(&pinners);
- Bitboard b = squares_between(s, ksq) & occupied_squares();
-
- assert(b);
+ b = squares_between(ksq, pop_1st_bit(&pinners)) & occupied_squares();
- if ( !(b & (b - 1)) // Only one bit set?
- && (b & pieces(c))) // Is an our piece?
+ // Only one bit set and is an our piece?
+ if (b && !(b & (b - 1)) && (b & pieces(sideToMove)))
result |= b;
}
return result;
/// Position:pinned_pieces() returns a bitboard of all pinned (against the
-/// king) pieces for the given color. Note that checkersBB bitboard must
-/// be already updated.
+/// king) pieces for the side to move.
-Bitboard Position::pinned_pieces(Color c) const {
+Bitboard Position::pinned_pieces() const {
- return hidden_checkers<true>(c);
+ return hidden_checkers<true>();
}
/// Position:discovered_check_candidates() returns a bitboard containing all
-/// pieces for the given side which are candidates for giving a discovered
-/// check. Contrary to pinned_pieces() here there is no need of checkersBB
-/// to be already updated.
+/// pieces for the side to move which are candidates for giving a discovered
+/// check.
-Bitboard Position::discovered_check_candidates(Color c) const {
+Bitboard Position::discovered_check_candidates() const {
- return hidden_checkers<false>(c);
+ return hidden_checkers<false>();
}
/// Position::attackers_to() computes a bitboard containing all pieces which
bool Position::pl_move_is_legal(Move m, Bitboard pinned) const {
- assert(is_ok());
assert(move_is_ok(m));
- assert(pinned == pinned_pieces(side_to_move()));
+ assert(pinned == pinned_pieces());
Color us = side_to_move();
Square from = move_from(m);
bool Position::move_is_pl(const Move m) const {
- assert(is_ok());
-
Color us = sideToMove;
Color them = opposite_color(sideToMove);
Square from = move_from(m);
bool Position::move_gives_check(Move m, const CheckInfo& ci) const {
- assert(is_ok());
assert(move_is_ok(m));
- assert(ci.dcCandidates == discovered_check_candidates(side_to_move()));
+ assert(ci.dcCandidates == discovered_check_candidates());
assert(piece_color(piece_on(move_from(m))) == side_to_move());
Square from = move_from(m);
// Our StateInfo newSt is about going out of scope so copy
// its content before it disappears.
detach();
+
+ assert(is_ok());
}
void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveIsCheck) {
- assert(is_ok());
assert(move_is_ok(m));
assert(&newSt != st);
void Position::undo_move(Move m) {
- assert(is_ok());
assert(move_is_ok(m));
sideToMove = opposite_color(sideToMove);
void Position::do_null_move(StateInfo& backupSt) {
- assert(is_ok());
assert(!in_check());
// Back up the information necessary to undo the null move to the supplied
st->rule50++;
st->pliesFromNull = 0;
st->value += (sideToMove == WHITE) ? TempoValue : -TempoValue;
+
+ assert(is_ok());
}
void Position::undo_null_move() {
- assert(is_ok());
assert(!in_check());
// Restore information from the our backup StateInfo object
sideToMove = opposite_color(sideToMove);
st->rule50--;
st->gamePly--;
+
+ assert(is_ok());
}
void Position::flip() {
- assert(is_ok());
-
// Make a copy of current position before to start changing
const Position pos(*this, threadID);