Exemplo n.º 1
0
def check_escape(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline[1::2]:
        if node.board().is_check() or util.is_capture(node):
            return False
        if node.parent.board().legal_moves.count() < 3:
            return False
        if node.parent.board().is_check():
            return True
    return False
Exemplo n.º 2
0
def intermezzo(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline[1::2][1:]:
        if util.is_capture(node):
            capture_move = node.move
            capture_square = node.move.to_square
            op_node = node.parent
            assert isinstance(op_node, ChildNode)
            prev_pov_node = node.parent.parent
            assert isinstance(prev_pov_node, ChildNode)
            if not op_node.move.from_square in prev_pov_node.board().attackers(
                    not puzzle.pov, capture_square):
                if prev_pov_node.move.to_square != capture_square:
                    prev_op_node = prev_pov_node.parent
                    assert isinstance(prev_op_node, ChildNode)
                    return (prev_op_node.move.to_square == capture_square
                            and util.is_capture(prev_op_node) and capture_move
                            in prev_op_node.board().legal_moves)
    return False
Exemplo n.º 3
0
def quiet_move(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline:
        # on player move, not the last move of the puzzle
        if node.turn() != puzzle.pov and not node.is_end():
            # no check given or escaped
            if not node.board().checkers() and not node.parent.board(
            ).checkers():
                # no capture made or threatened
                if not util.is_capture(node):
                    return not util.attacked_opponent_pieces(
                        node.board(), node.move.to_square, puzzle.pov)
    return False
Exemplo n.º 4
0
def discovered_attack(puzzle: Puzzle) -> bool:
    if discovered_check(puzzle):
        return True
    for node in puzzle.mainline[1::2][1:]:
        if util.is_capture(node):
            between = SquareSet.between(node.move.from_square,
                                        node.move.to_square)
            if node.parent.move.to_square == node.move.to_square:
                return False
            prev = node.parent.parent
            if prev.move.from_square in between and node.move.to_square != prev.move.to_square:
                return True
    return False
Exemplo n.º 5
0
def defensive_move(puzzle: Puzzle) -> bool:
    # like quiet_move, but on last move
    # at least 3 legal moves
    if puzzle.mainline[-2].board().legal_moves.count() < 3:
        return False
    node = puzzle.mainline[-1]
    # no check given, no piece taken
    if node.board().is_check() or util.is_capture(node):
        return False
    # no piece attacked
    if util.attacked_opponent_pieces(node.board(), node.move.to_square,
                                     puzzle.pov):
        return False
    # no advanced pawn push
    return not util.is_advanced_pawn_move(node)
Exemplo n.º 6
0
def hanging_piece(puzzle: Puzzle) -> bool:
    if util.is_capture(
            puzzle.mainline[0]) or puzzle.mainline[0].board().is_check():
        return False
    to = puzzle.mainline[1].move.to_square
    captured = puzzle.mainline[0].board().piece_at(to)
    if captured and captured.piece_type != PAWN:
        if util.is_hanging(puzzle.mainline[0].board(), captured, to):
            if len(puzzle.mainline) < 3:
                return True
            if material_diff(puzzle.mainline[3].board(),
                             puzzle.pov) >= material_diff(
                                 puzzle.mainline[1].board(), puzzle.pov):
                return True
    return False
Exemplo n.º 7
0
def quiet_move(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline:
        if (
                # on player move, not the last move of the puzzle
                node.turn() != puzzle.pov and not node.is_end() and
                # no check given or escaped
                not node.board().is_check()
                and not node.parent.board().is_check() and
                # no capture made or threatened
                not util.is_capture(node)
                and not util.attacked_opponent_pieces(
                    node.board(), node.move.to_square, puzzle.pov) and
                # no advanced pawn push
                not util.is_advanced_pawn_move(node)
                and util.moved_piece_type(node) != KING):
            return True
    return False
Exemplo n.º 8
0
def discovered_attack(puzzle: Puzzle) -> bool:
    if discovered_check(puzzle):
        return True
    for node in puzzle.mainline[1::2][1:]:
        if util.is_capture(node):
            between = SquareSet.between(node.move.from_square,
                                        node.move.to_square)
            assert isinstance(node.parent, ChildNode)
            if node.parent.move.to_square == node.move.to_square:
                return False
            prev = node.parent.parent
            assert isinstance(prev, ChildNode)
            if (prev.move.from_square in between
                    and node.move.to_square != prev.move.to_square
                    and node.move.from_square != prev.move.to_square
                    and not util.is_castling(prev)):
                return True
    return False
Exemplo n.º 9
0
def x_ray(puzzle: Puzzle) -> bool:
    for node in puzzle.mainline[1::2][1:]:
        if not util.is_capture(node):
            continue
        prev_op_node = node.parent
        assert isinstance(prev_op_node, ChildNode)
        if prev_op_node.move.to_square != node.move.to_square or util.moved_piece_type(
                prev_op_node) == KING:
            continue
        prev_pl_node = prev_op_node.parent
        assert isinstance(prev_pl_node, ChildNode)
        if prev_pl_node.move.to_square != prev_op_node.move.to_square:
            continue
        if prev_op_node.move.from_square in SquareSet.between(
                node.move.from_square, node.move.to_square):
            return True

    return False
Exemplo n.º 10
0
def side_attack(puzzle: Puzzle, corner_file: int, king_files: List[int],
                nb_pieces: int) -> bool:
    back_rank = 7 if puzzle.pov else 0
    init_board = puzzle.mainline[0].board()
    king_square = init_board.king(not puzzle.pov)
    if (not king_square or square_rank(king_square) != back_rank
            or square_file(king_square) not in king_files
            or len(init_board.piece_map()) < nb_pieces or  # no endgames
            not any(node.board().is_check()
                    for node in puzzle.mainline[1::2])):
        return False
    score = 0
    corner = chess.square(corner_file, back_rank)
    for node in puzzle.mainline[1::2]:
        corner_dist = square_distance(corner, node.move.to_square)
        if node.board().is_check():
            score += 1
        if util.is_capture(node) and corner_dist <= 3:
            score += 1
        elif corner_dist >= 5:
            score -= 1
    return score >= 2