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