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
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
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
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