Beispiel #1
0
def optimal_victory_sequence(battle: Battle) -> tuple[int, list[Spell]]:
    return shortest_path(start=battle.initial_state(),
                         target=battle.victory_state(),
                         edges=lambda state: (
                             (state.after_turn(spell), spell, spell.cost)
                             for spell in state.castable_spells()),
                         description="finding victory sequence" +
                         (" (hard)" if battle.hard else ""))
Beispiel #2
0
 def safest_path(self,
                 origin: Pos = None,
                 destination: Pos = None) -> tuple[int, Path]:
     return shortest_path(start=origin or self.bounds.top_left,
                          target=destination or self.bounds.bottom_right,
                          edges=lambda pos: ((npos, npos, self[npos])
                                             for npos in adjacent(pos)
                                             if npos in self),
                          nodes_count=self.bounds.area)
Beispiel #3
0
def find_path(seed: int, start: Pos, end: Pos) -> tuple[int, list[Pos]]:
    assert not is_wall(seed, start), "cannot start in wall!"
    assert not is_wall(seed, end), "cannot end in wall!"
    distance, path = shortest_path(start=start,
                                   target=end,
                                   edges=lambda pos:
                                   ((n, n, 1)
                                    for n in open_neighbors(pos, seed)))
    return distance, [start] + path
Beispiel #4
0
def find_shortest_path(password: str,
                       start: Room = None,
                       end: Room = None) -> str:
    _, path = shortest_path(
        start=start or Room(),
        target=end or Room('...', BOUNDS.bottom_right),
        edges=lambda room: (
            (new_room, direction, 1)
            for direction, new_room in room.neighbors(password)))
    return ''.join(path)
Beispiel #5
0
def find_longest_path(password: str,
                      start: Room = None,
                      end: Room = None) -> str:
    _, path = shortest_path(
        start=start or Room(),
        target=end or Room('...', BOUNDS.bottom_right),
        edges=lambda room: (
            # to find the **longest** path instead of shortest, we have to hack the Dijkstra a bit:
            # - non-vault rooms have negative distance = go through as many as possible
            # - the vault room has very large distance = pick it only at the last possible moment
            (new_room, direction, 1 << 20 if new_room.is_vault() else -1)
            for direction, new_room in room.neighbors(password)))
    return ''.join(path)
def access_target_data(grid: Grid) -> tuple[int, list[Move]]:

    # TODO: optimize!

    def possible_moves(current_grid: Grid) -> Iterable[tuple[Grid, Move, int]]:
        target = current_grid.empty_node
        return (
            (current_grid.move_data(source, target), (source.pos, target.pos), 1)
            for source in current_grid.adjacent(target)
            if 0 < source.used <= target.size
        )

    return shortest_path(
        start=grid,
        target=Grid(
            nodes=grid.nodes.values(),  # whatever
            target_data_pos=grid.accessible_node.pos
        ),
        edges=possible_moves,
    )