Beispiel #1
0
def clearance(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline[1::2][1:]:
        board = node.board()
        if not node.parent.board().piece_at(node.move.to_square):
            piece = board.piece_at(node.move.to_square)
            if piece and piece.piece_type in util.ray_piece_types:
                prev = node.parent.parent
                assert prev
                prev_move = prev.move
                assert prev_move
                assert isinstance(node.parent, ChildNode)
                if (not prev_move.promotion
                        and prev_move.to_square != node.move.from_square
                        and prev_move.to_square != node.move.to_square
                        and not node.parent.board().is_check()
                        and (not board.is_check()
                             or util.moved_piece_type(node.parent) != KING)):
                    if (prev_move.from_square == node.move.to_square
                            or prev_move.from_square in SquareSet.between(
                                node.move.from_square, node.move.to_square)):
                        if prev.parent and not prev.parent.board().piece_at(
                                prev_move.to_square) or util.is_in_bad_spot(
                                    prev.board(), prev_move.to_square):
                            return True
    return False
Beispiel #2
0
def skewer(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline[1::2][1:]:
        prev = node.parent
        assert isinstance(prev, ChildNode)
        capture = prev.board().piece_at(node.move.to_square)
        if capture and util.moved_piece_type(
                node
        ) in util.ray_piece_types and not node.board().is_checkmate():
            between = SquareSet.between(node.move.from_square,
                                        node.move.to_square)
            op_move = prev.move
            assert op_move
            if (op_move.to_square == node.move.to_square
                    or not op_move.from_square in between):
                continue
            if (util.king_values[util.moved_piece_type(prev)] >
                    util.king_values[capture.piece_type] and
                    util.is_in_bad_spot(prev.board(), node.move.to_square)):
                return True
    return False
Beispiel #3
0
def fork(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline[1::2][:-1]:
        if util.moved_piece_type(node) is not KING:
            board = node.board()
            if util.is_in_bad_spot(board, node.move.to_square):
                continue
            nb = 0
            for (piece, square) in util.attacked_opponent_squares(
                    board, node.move.to_square, puzzle.pov):
                if piece.piece_type == PAWN:
                    continue
                if (util.king_values[piece.piece_type] >
                        util.king_values[util.moved_piece_type(node)]
                        or (util.is_hanging(board, piece, square)
                            and square not in board.attackers(
                                not puzzle.pov, node.move.to_square))):
                    nb += 1
            if nb > 1:
                return True
    return False