Esempio n. 1
0
def create_data_files(dest: str = './textworld_data',
                      verbose: bool = False,
                      force: bool = False):
    """
    Creates grammar files in the target directory.

    Will NOT overwrite files if they alredy exist (checked on per-file basis).

    Parameters
    ----------
    dest :
        The path to the directory where to dump the data files into.
    verbose :
        Print when skipping an existing file.
    force :
        Overwrite all existing files.
    """

    # Make sure the destination folder exists.
    maybe_mkdir(dest)

    # Knowledge base related files.
    _maybe_copytree(LOGIC_DATA_PATH,
                    pjoin(dest, "logic"),
                    force=force,
                    verbose=verbose)

    # Text generation related files.
    _maybe_copytree(TEXT_GRAMMARS_PATH,
                    pjoin(dest, "text_grammars"),
                    force=force,
                    verbose=verbose)
Esempio n. 2
0
def compile_game(game: Game,
                 game_name: Optional[str] = None,
                 metadata: Mapping = {},
                 game_logger: Optional[GameLogger] = None,
                 games_folder: str = "./gen_games",
                 force_recompile: bool = False,
                 file_type: str = ".ulx") -> str:
    """
    Compile a game.

    Arguments:
        game: Game object to compile.
        game_name: Name of the compiled file (without extension).
            If `None`, a unique name will be infered from the game object.
        metadata: (Deprecated) contains information about how the game
            object was generated.
        game_logger: Object used to log stats about generated games.
        games_folder: Path to the folder where the compiled game will
            be saved.
        force_recompile: If `True`, recompile game even if it already
            exists.
        file_type: Either .z8 (Z-Machine) or .ulx (Glulx).

    Returns:
        The path to compiled game.
    """
    game_name = game_name or game.metadata["uuid"]
    source = generate_inform7_source(game)
    maybe_mkdir(games_folder)

    if str2bool(os.environ.get("TEXTWORLD_FORCE_ZFILE", False)):
        file_type = ".z8"

    game_json = pjoin(games_folder, game_name + ".json")
    meta_json = pjoin(games_folder, game_name + ".meta")
    game_file = pjoin(games_folder, game_name + file_type)

    already_compiled = False  # Check if game is already compiled.
    if not force_recompile and os.path.isfile(game_file) and os.path.isfile(
            game_json):
        already_compiled = game == Game.load(game_json)
        msg = (
            "It's highly unprobable that two games with the same id have different structures."
            " That would mean the generator has been modified."
            " Please clean already generated games found in '{}'.".format(
                games_folder))
        assert already_compiled, msg

    if not already_compiled or force_recompile:
        json.dump(metadata, open(meta_json, 'w'))
        game.save(game_json)
        compile_inform7_game(source, game_file)

    if game_logger is not None:
        game_logger.collect(game)

    return game_file
Esempio n. 3
0
def compile_game(game: Game, path: str, force_recompile: bool = False):
    """
    Compile a game.

    Arguments:
        game: Game object to compile.
        path: Path of the compiled game (.ulx or .z8). Also, the source (.ni)
              and metadata (.json) files will be saved along with it.
        force_recompile: If `True`, recompile game even if it already exists.

    Returns:
        The path to compiled game.
    """

    folder, filename = os.path.split(path)
    if not filename:
        filename = game.metadata.get("uuid", str(uuid.uuid4()))

    filename, ext = os.path.splitext(filename)
    if not ext:
        ext = ".ulx"  # Add default extension, if needed.

    if str2bool(os.environ.get("TEXTWORLD_FORCE_ZFILE", False)):
        ext = ".z8"

    source = generate_inform7_source(game)

    maybe_mkdir(folder)
    game_json = pjoin(folder, filename + ".json")
    game_file = pjoin(folder, filename + ext)

    already_compiled = False  # Check if game is already compiled.
    if not force_recompile and os.path.isfile(game_file) and os.path.isfile(
            game_json):
        already_compiled = game == Game.load(game_json)
        msg = (
            "It's highly unprobable that two games with the same id have different structures."
            " That would mean the generator has been modified."
            " Please clean already generated games found in '{}'.".format(
                folder))
        assert already_compiled, msg

    if not already_compiled or force_recompile:
        game.save(game_json)
        compile_inform7_game(source, game_file)

    return game_file
Esempio n. 4
0
def compile_game(game: Game, options: Optional[GameOptions] = None):
    """
    Compile a game.

    Arguments:
        game: Game object to compile.
        options:
            For customizing the game generation (see
            :py:class:`textworld.GameOptions <textworld.generator.game.GameOptions>`
            for the list of available options).

    Returns:
        The path to compiled game.
    """
    options = options or GameOptions()

    folder, filename = os.path.split(options.path)
    if not filename:
        filename = game.metadata.get("uuid", str(uuid.uuid4()))

    filename, ext = os.path.splitext(filename)
    if not ext:
        ext = options.file_ext  # Add default extension, if needed.

    source = generate_inform7_source(game)

    maybe_mkdir(folder)
    game_json = pjoin(folder, filename + ".json")
    game_file = pjoin(folder, filename + ext)

    already_compiled = False  # Check if game is already compiled.
    if not options.force_recompile and os.path.isfile(
            game_file) and os.path.isfile(game_json):
        already_compiled = game == Game.load(game_json)
        msg = (
            "It's highly unprobable that two games with the same id have different structures."
            " That would mean the generator has been modified."
            " Please clean already generated games found in '{}'.".format(
                folder))
        assert already_compiled, msg

    if not already_compiled or options.force_recompile:
        game.save(game_json)
        compile_inform7_game(source, game_file)

    return game_file
Esempio n. 5
0
def get_experiment_dir(config, makedir=True):
    env_id = config['general']['env_id']
    exps_dir = config['general']['experiments_dir']
    exp_tag = config['general']['experiment_tag']
    exp_dir = pjoin(exps_dir, env_id + "_" + exp_tag)
    if makedir:
        return maybe_mkdir(exp_dir)
    else:
        return exp_dir
Esempio n. 6
0
def visualize(world: Union[Game, State, GameState, World],
              interactive: bool = False):
    """
    Show the current state of the world.
    :param world: Object representing a game state to be visualized.
    :param interactive: Whether or not to visualize the state in the browser.
    :return: Image object of the visualization.
    """
    try:
        import webbrowser
        from textworld.render.serve import get_html_template
    except ImportError:
        raise ImportError(
            'Visualization dependencies not installed. Try running `pip install textworld[vis]`'
        )

    if isinstance(world, Game):
        game = world
        state = load_state(game.world, game.infos)
        state["objective"] = game.objective
    elif isinstance(world, GameState):
        state = load_state_from_game_state(game_state=world)
    elif isinstance(world, World):
        state = load_state(world)
    elif isinstance(world, State):
        state = world
        world = World.from_facts(state.facts)
        state = load_state(world)
    else:
        raise ValueError("Don't know how to visualize: {!r}".format(world))

    state["command"] = ""
    state["history"] = ""
    html = get_html_template(game_state=json.dumps(state))
    tmpdir = maybe_mkdir(pjoin(tempfile.gettempdir(), "textworld"))
    fh, filename = tempfile.mkstemp(suffix=".html", dir=tmpdir, text=True)
    url = 'file://' + filename
    with open(filename, 'w') as f:
        f.write(html)

    img_graph = take_screenshot(url, id="world")
    img_inventory = take_screenshot(url, id="inventory")
    image = concat_images(
        img_inventory,
        img_graph,
    )

    if interactive:
        try:
            webbrowser.open(url)
        finally:
            return image

    return image
Esempio n. 7
0
def visualize(world: Union[Game, State, GlulxGameState, World],
              interactive: bool = False):
    """
    Show the current state of the world.
    :param world: Object representing a game state to be visualized.
    :param interactive: Whether or not to visualize the state in the browser.
    :return: Image object of the visualization.
    """
    if isinstance(world, Game):
        game = world
        state = load_state(game.world, game.infos)
        state["objective"] = ""
        if len(game.quests) > 0:
            state["objective"] = game.quests[0].desc
    elif isinstance(world, GlulxGameState):
        state = load_state_from_game_state(game_state=world)
    elif isinstance(world, World):
        state = load_state(world)
    elif isinstance(world, State):
        state = world
        world = World.from_facts(state.facts)
        state = load_state(world)
    else:
        raise ValueError("Don't know how to visualize: {!r}".format(world))

    state["command"] = ""
    state["history"] = ""
    html = textworld.render.serve.get_html_template(
        game_state=json.dumps(state))
    tmpdir = maybe_mkdir(pjoin(tempfile.gettempdir(), "textworld"))
    fh, filename = tempfile.mkstemp(suffix=".html", dir=tmpdir, text=True)
    url = 'file://' + filename
    with open(filename, 'w') as f:
        f.write(html)

    image = take_screenshot(url)
    if interactive:
        try:
            webbrowser.open(url)
        finally:
            return image

    return image
Esempio n. 8
0
def get_experiment_dir(config):
    env_id = config['general']['env_id']
    exps_dir = config['general']['experiments_dir']
    exp_tag = config['general']['experiment_tag']
    exp_dir = pjoin(exps_dir, env_id + "_" + exp_tag)
    return maybe_mkdir(exp_dir)