X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=5b2efabec3181399592b564bbbaddf1758a4b064;hp=6022518e80b4b2330975c6a673b98bedf3e60d90;hb=805afcbf3d5db39c85b759232cfb99ab0a250311;hpb=4c5cbb1b14b283679e3e0096b7973c97b75088f3 diff --git a/src/position.cpp b/src/position.cpp index 6022518e..5b2efabe 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -81,25 +81,6 @@ PieceType min_attacker(const Bitboard*, Square, Bitboard, Bitboard&, Bitbo } // namespace -/// CheckInfo constructor - -CheckInfo::CheckInfo(const Position& pos) { - - Color them = ~pos.side_to_move(); - ksq = pos.square(them); - - pinned = pos.pinned_pieces(pos.side_to_move()); - dcCandidates = pos.discovered_check_candidates(); - - checkSquares[PAWN] = pos.attacks_from(ksq, them); - checkSquares[KNIGHT] = pos.attacks_from(ksq); - checkSquares[BISHOP] = pos.attacks_from(ksq); - checkSquares[ROOK] = pos.attacks_from(ksq); - checkSquares[QUEEN] = checkSquares[BISHOP] | checkSquares[ROOK]; - checkSquares[KING] = 0; -} - - /// operator<<(Position) returns an ASCII representation of the position std::ostream& operator<<(std::ostream& os, const Position& pos) { @@ -311,6 +292,24 @@ void Position::set_castling_right(Color c, Square rfrom) { } +/// Position::set_check_info() sets king attacks to detect if a move gives check + +void Position::set_check_info(CheckInfo* ci) const { + + ci->blockersForKing[WHITE] = slider_blockers(pieces(BLACK), square(WHITE)); + ci->blockersForKing[BLACK] = slider_blockers(pieces(WHITE), square(BLACK)); + + Square ksq = ci->ksq = square(~sideToMove); + + ci->checkSquares[PAWN] = attacks_from(ksq, ~sideToMove); + ci->checkSquares[KNIGHT] = attacks_from(ksq); + ci->checkSquares[BISHOP] = attacks_from(ksq); + ci->checkSquares[ROOK] = attacks_from(ksq); + ci->checkSquares[QUEEN] = ci->checkSquares[BISHOP] | ci->checkSquares[ROOK]; + ci->checkSquares[KING] = 0; +} + + /// Position::set_state() computes the hash keys of the position, and other /// data that once computed is updated incrementally as moves are made. /// The function is only used when a new position is set up, and to verify @@ -321,9 +320,10 @@ void Position::set_state(StateInfo* si) const { si->key = si->pawnKey = si->materialKey = 0; si->nonPawnMaterial[WHITE] = si->nonPawnMaterial[BLACK] = VALUE_ZERO; si->psq = SCORE_ZERO; - si->checkersBB = attackers_to(square(sideToMove)) & pieces(~sideToMove); + set_check_info(&si->ci); + for (Bitboard b = pieces(); b; ) { Square s = pop_lsb(&b); @@ -420,14 +420,14 @@ Phase Position::game_phase() const { } -/// Position::slider_blockers() returns a bitboard of all the pieces in 'target' that +/// Position::slider_blockers() returns a bitboard of all the pieces (both colors) that /// are blocking attacks on the square 's' from 'sliders'. A piece blocks a slider /// if removing that piece from the board would result in a position where square 's' /// is attacked. For example, a king-attack blocking piece can be either a pinned or /// a discovered check piece, according if its color is the opposite or the same of /// the color of the slider. -Bitboard Position::slider_blockers(Bitboard target, Bitboard sliders, Square s) const { +Bitboard Position::slider_blockers(Bitboard sliders, Square s) const { Bitboard b, pinners, result = 0; @@ -440,7 +440,7 @@ Bitboard Position::slider_blockers(Bitboard target, Bitboard sliders, Square s) b = between_bb(s, pop_lsb(&pinners)) & pieces(); if (!more_than_one(b)) - result |= b & target; + result |= b; } return result; } @@ -462,10 +462,9 @@ Bitboard Position::attackers_to(Square s, Bitboard occupied) const { /// Position::legal() tests whether a pseudo-legal move is legal -bool Position::legal(Move m, Bitboard pinned) const { +bool Position::legal(Move m) const { assert(is_ok(m)); - assert(pinned == pinned_pieces(sideToMove)); Color us = sideToMove; Square from = from_sq(m); @@ -500,7 +499,7 @@ bool Position::legal(Move m, Bitboard pinned) const { // A non-king move is legal if and only if it is not pinned or it // is moving along the ray towards or away from the king. - return !(pinned & from) + return !(pinned_pieces(us) & from) || aligned(from, to_sq(m), square(us)); } @@ -579,22 +578,21 @@ bool Position::pseudo_legal(const Move m) const { /// Position::gives_check() tests whether a pseudo-legal move gives a check -bool Position::gives_check(Move m, const CheckInfo& ci) const { +bool Position::gives_check(Move m) const { assert(is_ok(m)); - assert(ci.dcCandidates == discovered_check_candidates()); assert(color_of(moved_piece(m)) == sideToMove); Square from = from_sq(m); Square to = to_sq(m); // Is there a direct check? - if (ci.checkSquares[type_of(piece_on(from))] & to) + if (st->ci.checkSquares[type_of(piece_on(from))] & to) return true; // Is there a discovered check? - if ( (ci.dcCandidates & from) - && !aligned(from, to, ci.ksq)) + if ( (discovered_check_candidates() & from) + && !aligned(from, to, st->ci.ksq)) return true; switch (type_of(m)) @@ -603,7 +601,7 @@ bool Position::gives_check(Move m, const CheckInfo& ci) const { return false; case PROMOTION: - return attacks_bb(Piece(promotion_type(m)), to, pieces() ^ from) & ci.ksq; + return attacks_bb(Piece(promotion_type(m)), to, pieces() ^ from) & st->ci.ksq; // En passant capture with check? We have already handled the case // of direct checks and ordinary discovered check, so the only case we @@ -614,8 +612,8 @@ bool Position::gives_check(Move m, const CheckInfo& ci) const { Square capsq = make_square(file_of(to), rank_of(from)); Bitboard b = (pieces() ^ from ^ capsq) | to; - return (attacks_bb< ROOK>(ci.ksq, b) & pieces(sideToMove, QUEEN, ROOK)) - | (attacks_bb(ci.ksq, b) & pieces(sideToMove, QUEEN, BISHOP)); + return (attacks_bb< ROOK>(st->ci.ksq, b) & pieces(sideToMove, QUEEN, ROOK)) + | (attacks_bb(st->ci.ksq, b) & pieces(sideToMove, QUEEN, BISHOP)); } case CASTLING: { @@ -624,8 +622,8 @@ bool Position::gives_check(Move m, const CheckInfo& ci) const { Square kto = relative_square(sideToMove, rfrom > kfrom ? SQ_G1 : SQ_C1); Square rto = relative_square(sideToMove, rfrom > kfrom ? SQ_F1 : SQ_D1); - return (PseudoAttacks[ROOK][rto] & ci.ksq) - && (attacks_bb(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & ci.ksq); + return (PseudoAttacks[ROOK][rto] & st->ci.ksq) + && (attacks_bb(rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & st->ci.ksq); } default: assert(false); @@ -801,6 +799,9 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) { sideToMove = ~sideToMove; + // Update CheckInfo + set_check_info(&st->ci); + assert(pos_is_ok()); } @@ -914,6 +915,8 @@ void Position::do_null_move(StateInfo& newSt) { sideToMove = ~sideToMove; + set_check_info(&st->ci); + assert(pos_is_ok()); }