Ejemplo n.º 1
0
def main():
    args = parse_args()

    game = Game.load(args.game)

    # Sample quests.
    rng = np.random.RandomState(args.seed)
    chains = []
    rules_per_depth = {}

    for i in range(args.nb_quests):
        chain = sample_quest(game.world.state,
                             rng,
                             max_depth=args.quest_length,
                             allow_partial_match=False,
                             exceptions=[],
                             rules_per_depth=rules_per_depth,
                             backward=False)
        chains.append(chain)

    print_chains(chains, verbose=args.verbose)
    actions_tree = build_tree_from_chains(chains)

    # Convert tree to networkx graph/tree
    filename = "sample_tree.svg"
    G, labels = actions_tree.to_networkx()
    if len(G) > 0:
        tree = nx.bfs_tree(G, actions_tree.no)
        save_graph_to_svg(tree, labels, filename, backward=False)
    else:
        try:
            os.remove(filename)
        except:
            pass
Ejemplo n.º 2
0
def main():
    args = parse_args()

    seen = {}
    seen_solution = {}
    for game_path in args.games:
        game_path = game_path.replace(".ulx", ".json")
        game = Game.load(game_path)
        solution = tuple(game.quests[0].commands)

        if game in seen:
            print("Duplicate found:")
            print("  > {}".format(game_path))
            print("  > {}".format(seen[game]))
            print("-----")
            continue

        seen[game] = game_path

        if solution in seen_solution:
            print("Duplicate *solution* found:")
            print("  > {}".format(game_path))
            print("  > {}".format(seen_solution[solution]))
            print("-----")
            continue

        seen_solution[solution] = game_path
Ejemplo n.º 3
0
def main():
    args = parse_args()

    # Load game for which to sample quests for.
    game = Game.load(args.game.replace(".ulx", ".json"))

    options = ChainingOptions()
    options.backward = False
    options.max_depth = args.quest_length
    options.max_breadth = args.quest_breadth
    options.rules_per_depth = {}
    options.create_variables = False
    options.rng = np.random.RandomState(args.seed)

    # Sample quests.
    chains = []
    for i in range(args.nb_quests):
        chain = sample_quest(game.world.state, options)
        chains.append(chain)

    inform7 = Inform7Game(game)
    print_chains(chains, inform7)

    # Convert chains to networkx graph/tree
    filename_world = pjoin(args.output, "sample_world.png")
    filename_tree = pjoin(args.output, "sample_tree.svg")
    filename_graph = pjoin(args.output, "sample_graph.svg")
    G, labels = build_tree_from_chains(chains, inform7)
    if len(G) > 0:
        image = visualize(game)
        image.save(filename_world)
        tree = nx.bfs_tree(G, "root")
        save_graph_to_svg(tree, labels, filename_tree)
        save_graph_to_svg(G, labels, filename_graph)
    else:
        try:
            os.remove(filename_world)
            os.remove(filename_tree)
            os.remove(filename_graph)
        except:
            pass
Ejemplo n.º 4
0
def load_state(world: World,
               game_infos: Optional[Dict[str, EntityInfo]] = None,
               action: Optional[Action] = None,
               format: str = 'png',
               limit_player_view: bool = False) -> dict:
    """
    Generates serialization of game state.

    :param world: The current state of the world to visualize.
    :param game_infos: The mapping needed to get objects names.
    :param action: If provided, highlight the world changes made by that action.
    :param format: The graph output format (gv, svg, png...)
    :param limit_player_view: Whether to limit the player's view (defaults to false)
    :return: The graph generated from this World
    """

    if world.player_room is None:
        room = world.rooms[0]
    else:
        room = world.player_room

    edges = []
    nodes = sorted([room.name for room in world.rooms])
    pos = {room.name: (0, 0)}

    def used_pos():
        pos_along_edges = []
        for e in edges:
            A, B = pos[e[0]], pos[e[1]]
            if A[0] == B[0]:  # Y-axis edge.
                for i in range(A[1], B[1], np.sign(B[1] - A[1])):
                    pos_along_edges.append((A[0], i))
            else:  # X-axis edge.
                for i in range(A[0], B[0], np.sign(B[0] - A[0])):
                    pos_along_edges.append((i, A[1]))

        return list(pos.values()) + pos_along_edges

    openset = [room]
    closedset = set()

    # temp_viz(nodes, edges, pos, color=[world.player_room.name])
    while len(openset) > 0:
        room = openset.pop(0)
        closedset.add(room)

        for exit, target in room.exits.items():
            if target in openset or target in closedset:
                continue

            openset.append(target)

            src_pos = np.array(pos[room.name])
            if exit == "north":
                target_pos = tuple(src_pos + (0, 1))
                if target_pos in used_pos():
                    for n, p in pos.items():
                        if p[1] <= src_pos[1]:
                            pos[n] = (p[0], p[1] - 1)

                pos[target.name] = (pos[room.name][0], pos[room.name][1] + 1)

            elif exit == "south":
                target_pos = tuple(src_pos + (0, -1))
                if target_pos in used_pos():
                    for n, p in pos.items():
                        if p[1] >= src_pos[1]:
                            pos[n] = (p[0], p[1] + 1)

                pos[target.name] = (pos[room.name][0], pos[room.name][1] - 1)

            elif exit == "east":
                target_pos = tuple(src_pos + (1, 0))
                if target_pos in used_pos():
                    for n, p in pos.items():
                        if p[0] <= src_pos[0]:
                            pos[n] = (p[0] - 1, p[1])

                pos[target.name] = (pos[room.name][0] + 1, pos[room.name][1])

            elif exit == "west":
                target_pos = tuple(src_pos + (-1, 0))
                if target_pos in used_pos():
                    for n, p in pos.items():
                        if p[0] >= src_pos[0]:
                            pos[n] = (p[0] + 1, p[1])

                pos[target.name] = (pos[room.name][0] - 1, pos[room.name][1])

            edges.append((room.name, target.name, room.doors.get(exit)))
            # temp_viz(nodes, edges, pos, color=[world.player_room.name])

    pos = {game_infos[k].name: v for k, v in pos.items()}

    rooms = {}
    player_room = world.player_room
    if game_infos is None:
        new_game = Game(world, [])
        game_infos = new_game.infos
        game_infos["objective"] = new_game.quests[0].desc
        for k, v in game_infos.items():
            if v.name is None:
                v.name = k

    for room in world.rooms:
        rooms[room.id] = GraphRoom(game_infos[room.id].name, room)

    result = {}
    # Objective
    if "objective" in game_infos:
        result["objective"] = game_infos["objective"]

    # Objects
    all_items = {}
    inventory_items = []
    objects = world.objects
    # if limit_player_view:
    #     objects = world.get_visible_objects_in(world.player_room)
    #     objects += world.get_objects_in_inventory()

    # add all items first, in case properties are "out of order"
    for obj in objects:
        cur_item = GraphItem(obj.type, game_infos[obj.id].name)
        cur_item.portable = data.get_types().is_descendant_of(
            cur_item.type, "o")
        all_items[obj.id] = cur_item

    for obj in sorted(objects, key=lambda obj: obj.name):
        cur_item = all_items[obj.id]
        for attribute in obj.get_attributes():
            if action and attribute in action.added:
                cur_item.highlight = True

            if attribute.name == 'in':
                # add object to inventory
                if attribute.arguments[-1].type == 'I':
                    inventory_items.append(cur_item)
                elif attribute.arguments[0].name == obj.id:
                    # add object to containers if same object
                    all_items[attribute.arguments[1].name].add_content(
                        cur_item)
                else:
                    print('DEBUG: Skipping attribute %s for object %s' %
                          (attribute, obj.id))

            elif attribute.name == 'at':
                # add object to room
                if attribute.arguments[-1].type == 'r':
                    rooms[attribute.arguments[1].name].add_item(cur_item)
            elif attribute.name == 'on':
                # add object to supporters
                all_items[attribute.arguments[1].name].add_content(cur_item)
            elif attribute.name == 'open':
                cur_item.set_open_closed_locked('open')
            elif attribute.name == 'closed':
                cur_item.set_open_closed_locked('closed')
            elif attribute.name == 'locked':
                cur_item.set_open_closed_locked('locked')
                if not limit_player_view:
                    cur_item.infos = " (locked)"
            elif attribute.name == 'match':
                if not limit_player_view:
                    cur_item.infos = " (for {})".format(
                        game_infos[attribute.arguments[-1].name].name)
            else:
                cur_item.add_unknown_predicate(attribute)

    for room in rooms.values():
        room.position = pos[room.name]

    result["rooms"] = []
    for room in rooms.values():
        room.items = [item.to_dict() for item in room.items]
        temp = room.base_room.serialize()
        temp["attributes"] = [
            a.serialize() for a in room.base_room.get_attributes()
        ]
        room.base_room = temp
        result["rooms"].append(room.__dict__)

    def _get_door(door):
        if door is None:
            return None

        return all_items[door.name].__dict__

    result["connections"] = [{
        "src": game_infos[e[0]].name,
        "dest": game_infos[e[1]].name,
        'door': _get_door(e[2])
    } for e in edges]
    result["inventory"] = [inv.__dict__ for inv in inventory_items]

    return result