def load_state()

in textworld/render/render.py [0: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 = []
    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:
                edges.append((room.name, target.name, room.doors.get(exit)))
                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])

    rooms = {}
    if game_infos is None:
        new_game = Game(world)
        game_infos = new_game.infos
        for k, v in game_infos.items():
            if v.name is None:
                v.name = k

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

    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"]
        del game_infos["objective"]  # TODO: objective should not be part of game_infos in the first place.

    # 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 = KnowledgeBase.default().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__

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

    return result