From: Fabian Fichter Date: Thu, 11 Feb 2021 22:20:23 +0000 (+0100) Subject: Merge official-stockfish/master X-Git-Url: http://winboard.nl/cgi-bin?a=commitdiff_plain;h=2e3549ae3f9fa29d7c9c587c6d116c5f2e40a38a;p=fairystockfish.git Merge official-stockfish/master No functional change. --- 2e3549ae3f9fa29d7c9c587c6d116c5f2e40a38a diff --cc src/position.cpp index e23bda2,826e847..9e8ea44 --- a/src/position.cpp +++ b/src/position.cpp @@@ -955,56 -530,23 +955,54 @@@ bool Position::legal(Move m) const Direction step = to > from ? WEST : EAST; for (Square s = to; s != from; s += step) - if (attackers_to(s) & pieces(~us)) + if (attackers_to(s, ~us)) return false; + // TODO: need to consider touching kings + if (var->extinctionPseudoRoyal && attackers_to(from, ~us)) + return false; + + // Will the gate be blocked by king or rook? + Square rto = to + (to_sq(m) > from_sq(m) ? WEST : EAST); + if (is_gating(m) && (gating_square(m) == to || gating_square(m) == rto)) + return false; + - // In case of Chess960, verify that when moving the castling rook we do - // not discover some hidden checker. + // In case of Chess960, verify if the Rook blocks some checks // For instance an enemy queen in SQ_A1 when castling rook is in SQ_B1. - return !chess960 - || !(attackers_to(to, pieces() ^ to_sq(m), ~us)); - return !chess960 || !(blockers_for_king(us) & to_sq(m)); ++ return !chess960 || !attackers_to(to, pieces() ^ to_sq(m), ~us); } - // If the moving piece is a king, check whether the destination square is - // attacked by the opponent. - if (type_of(piece_on(from)) == KING) - return !(attackers_to(to) & pieces(~us)); + Bitboard occupied = (type_of(m) != DROP ? pieces() ^ from : pieces()) | to; + + // Flying general rule and bikjang + // In case of bikjang passing is always allowed, even when in check + if (st->bikjang && is_pass(m)) + return true; + if ((var->flyingGeneral && count(us)) || st->bikjang) + { + Square s = type_of(moved_piece(m)) == KING ? to : square(us); + if (attacks_bb(~us, ROOK, s, occupied) & pieces(~us, KING) & ~square_bb(to)) + return false; + } - // 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 !(blockers_for_king(us) & from) - || aligned(from, to, square(us)); + // Makpong rule + if (var->makpongRule && checkers() && type_of(moved_piece(m)) == KING && (checkers() ^ to)) + return false; + + // If the moving piece is a king, check whether the destination + // square is attacked by the opponent. Castling moves are checked + // for legality during move generation. + if (type_of(moved_piece(m)) == KING) + return type_of(m) == CASTLING || !attackers_to(to, occupied, ~us); + + Bitboard janggiCannons = pieces(JANGGI_CANNON); + if (type_of(moved_piece(m)) == JANGGI_CANNON) + janggiCannons = (type_of(m) == DROP ? janggiCannons : janggiCannons ^ from) | to; + else if (janggiCannons & to) + janggiCannons ^= to; + + // A non-king move is legal if the king is not under attack after the move. + return !count(us) || !(attackers_to(square(us), occupied, ~us, janggiCannons) & ~SquareBB[to]); } @@@ -1019,33 -561,14 +1017,35 @@@ bool Position::pseudo_legal(const Move Square to = to_sq(m); Piece pc = moved_piece(m); + // Illegal moves to squares outside of board + if (!(board_bb() & to)) + return false; + + // Use a fast check for piece drops + if (type_of(m) == DROP) + return piece_drops() + && pc != NO_PIECE + && color_of(pc) == us + && count_in_hand(us, in_hand_piece_type(m)) + && (drop_region(us, type_of(pc)) & ~pieces() & to) + && ( type_of(pc) == in_hand_piece_type(m) + || (drop_promoted() && type_of(pc) == promoted_piece_type(in_hand_piece_type(m)))); + // Use a slower but simpler function for uncommon cases + // yet we skip the legality check of MoveList(). - if (type_of(m) != NORMAL) + if (type_of(m) != NORMAL || is_gating(m) || arrow_gating()) - return MoveList(*this).contains(m); + return checkers() ? MoveList< EVASIONS>(*this).contains(m) + : MoveList(*this).contains(m); + // Handle the case where a mandatory piece promotion/demotion is not taken + if ( mandatory_piece_promotion() + && (is_promoted(from) ? piece_demotion() : promoted_piece_type(type_of(pc)) != NO_PIECE_TYPE) + && (zone_bb(us, promotion_rank(), max_rank()) & (SquareBB[from] | to)) + && (!piece_promotion_on_capture() || capture(m))) + return false; + // Is not a promotion, so promotion piece must be empty - if (promotion_type(m) - KNIGHT != NO_PIECE_TYPE) + if (promotion_type(m) != NO_PIECE_TYPE) return false; // If the 'from' square is not occupied by a piece belonging to the side to @@@ -1191,21 -660,18 +1191,19 @@@ bool Position::gives_check(Move m) cons Square capsq = make_square(file_of(to), rank_of(from)); Bitboard b = (pieces() ^ from ^ capsq) | to; - return (attacks_bb< ROOK>(square(~sideToMove), b) & pieces(sideToMove, QUEEN, ROOK)) - | (attacks_bb(square(~sideToMove), b) & pieces(sideToMove, QUEEN, BISHOP)); + return attackers_to(square(~sideToMove), b) & pieces(sideToMove) & b; } - case CASTLING: + default: //CASTLING { + // Castling is encoded as 'king captures the rook' - Square ksq = square(~sideToMove); - Square rto = relative_square(sideToMove, to > from ? SQ_F1 : SQ_D1); + Square kfrom = from; - Square rfrom = to; // Castling is encoded as 'king captures the rook' ++ Square rfrom = to; + Square kto = make_square(rfrom > kfrom ? castling_kingside_file() : castling_queenside_file(), castling_rank(sideToMove)); + Square rto = kto + (rfrom > kfrom ? WEST : EAST); - return (attacks_bb(rto) & ksq) - && (attacks_bb(rto, pieces() ^ from ^ to) & ksq); + return (PseudoAttacks[sideToMove][type_of(piece_on(rfrom))][rto] & square(~sideToMove)) + && (attacks_bb(sideToMove, type_of(piece_on(rfrom)), rto, (pieces() ^ kfrom ^ rfrom) | rto | kto) & square(~sideToMove)); } - default: - assert(false); - return false; } }