X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fposition.cpp;h=45be5df3203b26a0c4fe5ffccb25468033692ba0;hp=65964b827a889880ca1d8322e7c339d0b81494bc;hb=8de91be61e0910936e3d6be6e1033a4fb8537dca;hpb=7c84b39a42bfcada7e9eafd745a9616aaa8f9c1c diff --git a/src/position.cpp b/src/position.cpp index 65964b82..45be5df3 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? @@ -1208,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()); @@ -1414,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()); @@ -1422,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. @@ -1455,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;