X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=b8f7807b68aa5eb225a5b3aabcee248e6c5f06fb;hp=21839d6abaf32e52e48d027e4a9b626864496fc3;hb=b870f5a091793ea423de78e74f5652b9307cfcbd;hpb=68e711aac603388d38490521cf336b535aa10c91 diff --git a/src/position.cpp b/src/position.cpp index 21839d6a..b8f7807b 100644 --- a/src/position.cpp +++ b/src/position.cpp @@ -358,6 +358,24 @@ Bitboard Position::hidden_checkers(Color c) const { } +/// 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(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(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 @@ -461,7 +479,6 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const { return true; Color us = side_to_move(); - Color them = opposite_color(us); Square from = move_from(m); Square ksq = king_square(us); @@ -473,6 +490,7 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const { // after the move is made if (move_is_ep(m)) { + Color them = opposite_color(us); Square to = move_to(m); Square capsq = make_square(square_file(to), square_rank(from)); Bitboard b = occupied_squares(); @@ -493,11 +511,12 @@ bool Position::pl_move_is_legal(Move m, Bitboard pinned) const { // If the moving piece is a king, check whether the destination // square is attacked by the opponent. if (from == ksq) - return !(square_is_attacked(move_to(m), them)); + return !(square_is_attacked(move_to(m), opposite_color(us))); // 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 ( !bit_is_set(pinned, from) + return ( !pinned + || !bit_is_set(pinned, from) || (direction_between_squares(from, ksq) == direction_between_squares(move_to(m), ksq))); } @@ -533,7 +552,8 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const { if (bit_is_set(pawn_attacks(them, ksq), to)) // Normal check? return true; - if ( bit_is_set(dcCandidates, from) // Discovered check? + if ( dcCandidates // Discovered check? + && bit_is_set(dcCandidates, from) && (direction_between_squares(from, ksq) != direction_between_squares(to, ksq))) return true; @@ -572,22 +592,26 @@ bool Position::move_is_check(Move m, Bitboard dcCandidates) const { } return false; + // Test discovered check and normal check according to piece type case KNIGHT: - return bit_is_set(dcCandidates, from) // Discovered check? - || bit_is_set(piece_attacks(ksq), to); // Normal check? + return (dcCandidates && bit_is_set(dcCandidates, from)) + || bit_is_set(piece_attacks(ksq), to); case BISHOP: - return bit_is_set(dcCandidates, from) // Discovered check? - || bit_is_set(piece_attacks(ksq), to); // Normal check? + return (dcCandidates && bit_is_set(dcCandidates, from)) + || ( direction_between_squares(ksq, to) != DIR_NONE + && bit_is_set(piece_attacks(ksq), to)); case ROOK: - return bit_is_set(dcCandidates, from) // Discovered check? - || bit_is_set(piece_attacks(ksq), to); // Normal check? + return (dcCandidates && bit_is_set(dcCandidates, from)) + || ( direction_between_squares(ksq, to) != DIR_NONE + && bit_is_set(piece_attacks(ksq), to)); case QUEEN: // Discovered checks are impossible! assert(!bit_is_set(dcCandidates, from)); - return bit_is_set(piece_attacks(ksq), to); // Normal check? + return ( direction_between_squares(ksq, to) != DIR_NONE + && bit_is_set(piece_attacks(ksq), to)); case KING: // Discovered check? @@ -648,7 +672,18 @@ 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)) + 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(ksq), to)) // slow, try to early skip + set_bit(pCheckersBB, to); + + else if ( Piece != KING + && !Slider + && bit_is_set(piece_attacks(ksq), to)) set_bit(pCheckersBB, to); if (Piece != QUEEN && bit_is_set(dcCandidates, from)) @@ -1197,7 +1232,7 @@ void Position::undo_move(Move m) { 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()); @@ -1403,7 +1438,7 @@ void Position::undo_ep_move(Move m) { /// 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()); @@ -1411,10 +1446,12 @@ void Position::do_null_move(StateInfo& newSt) { // 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. @@ -1444,7 +1481,7 @@ void Position::undo_null_move() { 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; @@ -1817,15 +1854,14 @@ Value Position::compute_value() const { Value Position::compute_non_pawn_material(Color c) const { Value result = Value(0); - Square s; for (PieceType pt = KNIGHT; pt <= QUEEN; pt++) { Bitboard b = pieces_of_color_and_type(c, pt); - while(b) + while (b) { - s = pop_1st_bit(&b); - assert(piece_on(s) == piece_of_color_and_type(c, pt)); + assert(piece_on(first_1(b)) == piece_of_color_and_type(c, pt)); + pop_1st_bit(&b); result += piece_value_midgame(pt); } }