X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=ed7510101de89fbbd38270113019d82b710d8b7a;hp=c24d5675d8c1dadbb1de958a5fdd65c276a02be7;hb=a188a047ab79a742e55f157f29e30299baafa7d0;hpb=aaad48464bc8a269634de371238826d09a6e240d diff --git a/src/position.cpp b/src/position.cpp index c24d5675..ed751010 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -60,11 +60,11 @@ static bool RequestPending = false; /// Constructors -Position::Position(const Position &pos) { +Position::Position(const Position& pos) { copy(pos); } -Position::Position(const std::string &fen) { +Position::Position(const std::string& fen) { from_fen(fen); } @@ -73,7 +73,7 @@ Position::Position(const std::string &fen) { /// string. This function is not very robust - make sure that input FENs are /// correct (this is assumed to be the responsibility of the GUI). -void Position::from_fen(const std::string &fen) { +void Position::from_fen(const std::string& fen) { static const std::string pieceLetters = "KQRBNPkqrbnp"; static const Piece pieces[] = { WK, WQ, WR, WB, WN, WP, BK, BQ, BR, BB, BN, BP }; @@ -317,6 +317,25 @@ void Position::copy(const Position &pos) { } +/// Position::update_checkers() updates checkers info, used in do_move() +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)) + set_bit(pCheckersBB, to); + + if (Piece != QUEEN && bit_is_set(dcCandidates, from)) + { + if (Piece != ROOK) + (*pCheckersBB) |= (piece_attacks(ksq) & rooks_and_queens(side_to_move())); + + if (Piece != BISHOP) + (*pCheckersBB) |= (piece_attacks(ksq) & bishops_and_queens(side_to_move())); + } +} + + /// Position:pinned_pieces() returns a bitboard of all pinned (against the /// king) pieces for the given color. Bitboard Position::pinned_pieces(Color c) const { @@ -379,19 +398,6 @@ Bitboard Position::hidden_checks(Color c, Square ksq) const { } -/// Position::square_is_attacked() checks whether the given side attacks the -/// given square. - -bool Position::square_is_attacked(Square s, Color c) const { - - return (pawn_attacks(opposite_color(c), s) & pawns(c)) - || (piece_attacks(s) & knights(c)) - || (piece_attacks(s) & kings(c)) - || (piece_attacks(s) & rooks_and_queens(c)) - || (piece_attacks(s) & bishops_and_queens(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 @@ -407,12 +413,6 @@ Bitboard Position::attacks_to(Square s) const { | (piece_attacks(s) & pieces_of_type(KING)); } -Bitboard Position::attacks_to(Square s, Color c) const { - - return attacks_to(s) & pieces_of_color(c); -} - - /// Position::piece_attacks_square() tests whether the piece on square f /// attacks square t. @@ -808,33 +808,34 @@ void Position::do_move(Move m, UndoInfo& u, Bitboard dcCandidates) { if (piece == KING) kingSquare[us] = to; - // If the move was a double pawn push, set the en passant square. - // This code is a bit ugly right now, and should be cleaned up later. - // FIXME + // Reset en passant square if (epSquare != SQ_NONE) { key ^= zobEp[epSquare]; epSquare = SQ_NONE; } + + // If the moving piece was a pawn do some special extra work if (piece == PAWN) { + // Reset rule 50 draw counter + rule50 = 0; + + // Update pawn hash key + pawnKey ^= zobrist[us][PAWN][from] ^ zobrist[us][PAWN][to]; + + // Set en passant square, only if moved pawn can be captured if (abs(int(to) - int(from)) == 16) { - if( ( us == WHITE - && (pawn_attacks(WHITE, from + DELTA_N) & pawns(BLACK))) - || ( us == BLACK - && (pawn_attacks(BLACK, from + DELTA_S) & pawns(WHITE)))) + if ( (us == WHITE && (pawn_attacks(WHITE, from + DELTA_N) & pawns(BLACK))) + || (us == BLACK && (pawn_attacks(BLACK, from + DELTA_S) & pawns(WHITE)))) { epSquare = Square((int(from) + int(to)) / 2); key ^= zobEp[epSquare]; } } - // Reset rule 50 draw counter - rule50 = 0; - - // Update pawn hash key - pawnKey ^= zobrist[us][PAWN][from] ^ zobrist[us][PAWN][to]; } + // Update piece lists pieceList[us][piece][index[from]] = to; index[to] = index[from]; @@ -845,54 +846,33 @@ void Position::do_move(Move m, UndoInfo& u, Bitboard dcCandidates) { castleRights &= castleRightsMask[to]; key ^= zobCastle[castleRights]; - // Update checkers bitboard + // Update checkers bitboard, piece must be already moved checkersBB = EmptyBoardBB; Square ksq = king_square(them); switch (piece) { case PAWN: - if (bit_is_set(pawn_attacks(them, ksq), to)) - set_bit(&checkersBB, to); - - if (bit_is_set(dcCandidates, from)) - checkersBB |= ( (piece_attacks(ksq) & rooks_and_queens(us)) - |(piece_attacks(ksq) & bishops_and_queens(us))); + update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; case KNIGHT: - if (bit_is_set(piece_attacks(ksq), to)) - set_bit(&checkersBB, to); - - if (bit_is_set(dcCandidates, from)) - checkersBB |= ( (piece_attacks(ksq) & rooks_and_queens(us)) - |(piece_attacks(ksq) & bishops_and_queens(us))); + update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; case BISHOP: - if (bit_is_set(piece_attacks(ksq), to)) - set_bit(&checkersBB, to); - - if (bit_is_set(dcCandidates, from)) - checkersBB |= (piece_attacks(ksq) & rooks_and_queens(us)); + update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; case ROOK: - if (bit_is_set(piece_attacks(ksq), to)) - set_bit(&checkersBB, to); - - if (bit_is_set(dcCandidates, from)) - checkersBB |= (piece_attacks(ksq) & bishops_and_queens(us)); + update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; case QUEEN: - if (bit_is_set(piece_attacks(ksq), to)) - set_bit(&checkersBB, to); + update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; case KING: - if (bit_is_set(dcCandidates, from)) - checkersBB |= ( (piece_attacks(ksq) & rooks_and_queens(us)) - |(piece_attacks(ksq) & bishops_and_queens(us))); + update_checkers(&checkersBB, ksq, from, to, dcCandidates); break; default: @@ -912,7 +892,6 @@ void Position::do_move(Move m, UndoInfo& u, Bitboard dcCandidates) { assert(is_ok()); } - /// Position::do_capture_move() is a private method used to update captured /// piece info. It is called from the main Position::do_move function. @@ -1626,6 +1605,21 @@ int Position::see(Square from, Square to) const { // Find all attackers to the destination square, with the moving piece // removed, but possibly an X-ray attacker added behind it. occ = occupied_squares(); + + // Handle enpassant moves + if (ep_square() == to && type_of_piece_on(from) == PAWN) + { + assert(capture == EMPTY); + + Square capQq = (side_to_move() == WHITE)? (to - DELTA_N) : (to - DELTA_S); + capture = piece_on(capQq); + + assert(type_of_piece_on(capQq) == PAWN); + + // Remove the captured pawn + clear_bit(&occ, capQq); + } + while (true) { clear_bit(&occ, from); @@ -1952,7 +1946,7 @@ Value Position::compute_non_pawn_material(Color c) const { /// side to move is checkmated. Note that this function is currently very /// slow, and shouldn't be used frequently inside the search. -bool Position::is_mate() { +bool Position::is_mate() const { if (is_check()) {