def test_making_a_custom_game(): with make_temp_directory(prefix="test_tw-make") as tmpdir: output_folder = pjoin(tmpdir, "gen_games") game_file = pjoin(output_folder, "game_1234.ulx") command = [ "tw-make", "custom", "--seed", "1234", "--output", game_file ] assert check_call(command) == 0 assert os.path.isdir(output_folder) assert os.path.isfile(game_file) # Solve the game using WalkthroughAgent. agent = textworld.agents.WalkthroughAgent() textworld.play(game_file, agent=agent, silent=True) with make_temp_directory(prefix="test_tw-make") as tmpdir: output_folder = pjoin(tmpdir, "gen_games") game_file = pjoin(output_folder, "game_1234") # Default extension is .ulx command = [ "tw-make", "custom", "--seed", "1234", "--output", game_file ] assert check_call(command) == 0 assert os.path.isdir(output_folder) assert os.path.isfile(game_file + ".ulx") # Solve the game using WalkthroughAgent. agent = textworld.agents.WalkthroughAgent() textworld.play(game_file + ".ulx", agent=agent, silent=True) with make_temp_directory(prefix="test_tw-make") as tmpdir: output_folder = pjoin(tmpdir, "gen_games", "") command = [ "tw-make", "custom", "--seed", "1234", "--output", output_folder ] assert check_call(command) == 0 assert os.path.isdir(output_folder) game_file = glob.glob(pjoin(output_folder, "*.ulx"))[0] # Solve the game using WalkthroughAgent. agent = textworld.agents.WalkthroughAgent() textworld.play(game_file, agent=agent, silent=True) with make_temp_directory(prefix="test_tw-make") as tmpdir: output_folder = pjoin(tmpdir, "gen_games") command = [ "tw-make", "custom", "--seed", "1234", "--output", output_folder ] assert check_call(command) == 0 assert os.path.isfile(output_folder + ".ulx") # Solve the game using WalkthroughAgent. agent = textworld.agents.WalkthroughAgent() textworld.play(output_folder + ".ulx", agent=agent, silent=True)
def test_registering_zmachine_game(self): with make_temp_directory() as tmpdir: options = textworld.GameOptions() options.path = tmpdir options.seeds = 1234 options.file_ext = ".z8" gamefile, game = textworld.make(options) os.remove(gamefile.replace( ".z8", ".json")) # Simulate an non-TextWorld Z-Machine game. env_options = EnvInfos(extras=["walkthrough"]) env_id = textworld.gym.register_game(gamefile, env_options, name="test-zmachine") env = gym.make(env_id) obs, infos = env.reset() assert len(infos) == len(env_options) for cmd in game.metadata["walkthrough"]: obs, score, done, infos = env.step(cmd) assert done assert score == 1 env.close()
def test_limit_wrapper(): # Make a game for testing purposes. max_episode_steps = 7 num_nodes = 3 num_items = 10 options = textworld.GameOptions() options.seeds = 1234 options.nb_rooms = num_nodes options.nb_objects = num_items options.quest_length = 3 options.grammar.theme = "house" options.grammar.include_adj = True game = textworld.generator.make_game(options) game_name = "test_limit_wrapper" with make_temp_directory(prefix=game_name) as tmpdir: options.path = tmpdir game_file = compile_game(game, options) env = textworld.start(game_file) env = Limit(env, max_episode_steps) state = env.reset() done = False assert state["moves"] == 0 for no_step in range(1, max_episode_steps + 1): assert not done state, score, done = env.step("wait") assert state["moves"] == no_step assert done
def test_filter_wrapper(): # Make a game for testing purposes. num_nodes = 3 num_items = 10 options = textworld.GameOptions() options.seeds = 1234 options.nb_rooms = num_nodes options.nb_objects = num_items options.quest_length = 3 options.grammar.theme = "house" options.grammar.include_adj = True game = textworld.generator.make_game(options) game_name = "test_filter_wrapper" with make_temp_directory(prefix=game_name) as tmpdir: options.path = tmpdir game_file = compile_game(game, options) env = textworld.start(game_file) env_options = EnvInfos() for attr in env_options.__slots__: if attr == "extras": continue # Skip since it's not a boolean attribute. setattr(env_options, attr, True) assert len(env_options) == len(env_options.__slots__) - 1 assert len(env_options) == len(env_options.basics) env = Filter(env, env_options) _, infos = env.reset() for attr in env_options.basics: assert attr in infos
def test_missing_game_infos_file(): with make_temp_directory() as tmpdir: game_file = pjoin(tmpdir, "tmp.ulx") with open(game_file, "w"): pass # Empty file npt.assert_raises(MissingGameInfosError, textworld.start, game_file)
def new_quest_using_commands(self, commands: List[str]) -> Quest: """ Creates a new quest using predefined text commands. This launches a `textworld.play` session to execute provided commands. Args: commands: Text commands. Returns: The resulting quest. """ with make_temp_directory() as tmpdir: try: game_file = self.compile(pjoin(tmpdir, "record_quest.ulx")) recorder = Recorder() agent = textworld.agents.WalkthroughAgent(commands) textworld.play(game_file, agent=agent, wrapper=recorder, silent=True) except textworld.agents.WalkthroughDone: pass # Quest is done. # Skip "None" actions. actions = [action for action in recorder.actions if action is not None] return Quest(actions=actions)
def new_event_using_commands(self, commands: List[str]) -> Event: """ Creates a new event using predefined text commands. This launches a `textworld.play` session to execute provided commands. Args: commands: Text commands. Returns: The resulting event. """ with make_temp_directory() as tmpdir: try: game_file = self.compile(pjoin(tmpdir, "record_event.ulx")) recorder = Recorder() agent = textworld.agents.WalkthroughAgent(commands) textworld.play(game_file, agent=agent, wrappers=[recorder], silent=True) except textworld.agents.WalkthroughDone: pass # Quest is done. # Skip "None" actions. actions, commands = zip(*[(a, c) for a, c in zip(recorder.actions, commands) if a is not None]) event = Event(actions=actions, commands=commands) return event
def test_making_game_with_names_to_exclude(): g_rng.set_seed(42) with make_temp_directory(prefix="test_render_wrapper") as tmpdir: game_file1, game1 = textworld.make(2, 20, 3, 3, {"names_to_exclude": []}, seed=123, games_dir=tmpdir) game1_objects_names = [ info.name for info in game1.infos.values() if info.name is not None ] game_file2, game2 = textworld.make( 2, 20, 3, 3, {"names_to_exclude": game1_objects_names}, seed=123, games_dir=tmpdir) game2_objects_names = [ info.name for info in game2.infos.values() if info.name is not None ] assert len(set(game1_objects_names) & set(game2_objects_names)) == 0
def test_record_quest_from_commands(play_the_game=False): M = GameMaker() # The goal commands = ["go east", "insert ball into chest"] # Create a 'bedroom' room. R1 = M.new_room("bedroom") R2 = M.new_room("kitchen") M.set_player(R1) path = M.connect(R1.east, R2.west) path.door = M.new(type='d', name='wooden door') path.door.add_property("open") ball = M.new(type='o', name='ball') M.inventory.add(ball) # Add a closed chest in R2. chest = M.new(type='c', name='chest') chest.add_property("open") R2.add(chest) M.set_quest_from_commands(commands) game = M.build() with make_temp_directory( prefix="test_record_quest_from_commands") as tmpdir: game_file = _compile_game(game, folder=tmpdir) if play_the_game: textworld.play(game_file) else: agent = textworld.agents.WalkthroughAgent(commands) textworld.play(game_file, agent=agent, silent=True)
def test_playing_generated_games(): NB_GAMES = 10 rng = np.random.RandomState(1234) for i in range(NB_GAMES): # Sample game specs. world_size = rng.randint(1, 10) nb_objects = rng.randint(0, 20) quest_length = rng.randint(2, 5) quest_breadth = rng.randint(3, 7) game_seed = rng.randint(0, 65365) with make_temp_directory(prefix="test_play_generated_games") as tmpdir: options = textworld.GameOptions() options.nb_rooms = world_size options.nb_objects = nb_objects options.quest_length = quest_length options.quest_breadth = quest_breadth options.seeds = game_seed game_file, game = textworld.make(options, path=tmpdir) # Solve the game using WalkthroughAgent. agent = textworld.agents.WalkthroughAgent() textworld.play(game_file, agent=agent, silent=True) # Play the game using RandomAgent and make sure we can always finish the # game by following the winning policy. env = textworld.start(game_file) agent = textworld.agents.RandomCommandAgent() agent.reset(env) env.compute_intermediate_reward() env.seed(4321) game_state = env.reset() max_steps = 100 reward = 0 done = False for step in range(max_steps): command = agent.act(game_state, reward, done) game_state, reward, done = env.step(command) if done: msg = "Finished before playing `max_steps` steps because of command '{}'.".format(command) if game_state.has_won: msg += " (winning)" assert len(game_state._game_progression.winning_policy) == 0 if game_state.has_lost: msg += " (losing)" assert game_state._game_progression.winning_policy is None print(msg) break # Make sure the game can still be solved. winning_policy = game_state._game_progression.winning_policy assert len(winning_policy) > 0 assert game_state.state.is_sequence_applicable(winning_policy)
def test_making_a_game_without_a_quest(play_the_game=False): rng_map = np.random.RandomState(1234) map_ = textworld.generator.make_small_map(1, rng_map) world = World.from_map(map_) world.set_player_room() # First room generated (i.e. the only one). rng_objects = np.random.RandomState(1234) nb_objects = 10 world.populate(nb_objects, rng=rng_objects) quests = [] # Define the grammar we'll use. rng_grammar = np.random.RandomState(1234) grammar_flags = { "theme": "house", "include_adj": False, "only_last_action": True, "blend_instructions": True, "blend_descriptions": True, "refer_by_name_only": True, "instruction_extension": [], } grammar = textworld.generator.make_grammar(grammar_flags, rng=rng_grammar) # Generate the world representation. game = textworld.generator.make_game_with(world, quests, grammar) with make_temp_directory(prefix="test_render_wrapper") as tmpdir: options = textworld.GameOptions() options.path = tmpdir game_file = compile_game(game, options) if play_the_game: textworld.play(game_file)
def test_disambiguation_questions(): M = textworld.GameMaker() room = M.new_room("room") M.set_player(room) tasty_apple = M.new(type="o", name="tasty apple") tasty_orange = M.new(type="o", name="tasty orange") room.add(tasty_apple, tasty_orange) game = M.build() game_name = "test_names_disambiguation" with make_temp_directory(prefix=game_name) as tmpdir: game_file = _compile_game(game, path=tmpdir) env = textworld.start(game_file, EnvInfos(description=True, inventory=True)) game_state = env.reset() previous_inventory = game_state.inventory previous_description = game_state.description game_state, _, _ = env.step("take tasty") assert "?" in game_state.feedback # Disambiguation question. # When there is a question in Inform7, the next string sent to the game # will be considered as the answer. We now make sure that asking for # extra information like `description` or `inventory` before answering # the question works. assert game_state.description == previous_description assert game_state.inventory == previous_inventory # Now answering the question. game_state, _, _ = env.step("apple") assert "That's not a verb I recognise." not in game_state.feedback assert "tasty orange" not in game_state.inventory assert "tasty apple" in game_state.inventory assert "tasty apple" not in game_state.description
def test_batch_sync(): batch_size = 5 with make_temp_directory() as tmpdir: options = textworld.GameOptions() options.path = tmpdir options.seeds = 1234 options.file_ext = ".ulx" gamefile1, game = textworld.make(options) options.file_ext = ".z8" gamefile2, game = textworld.make(options) env_options = EnvInfos(inventory=True, description=True, admissible_commands=True, extras=["walkthrough"]) env_id = textworld.gym.register_games([gamefile1, gamefile2], request_infos=env_options, batch_size=batch_size, name="test-batch", asynchronous=False) env = gym.make(env_id) obs, infos = env.reset() assert len(obs) == batch_size assert len(set(obs)) == 1 # All the same game. assert len(infos) == len(env_options) for values in infos.values(): assert len(values) == batch_size for cmds in infos.get("extra.walkthrough"): obs, scores, dones, infos = env.step(cmds) env.close() assert all(dones) assert all(score == 1 for score in scores)
def test_html_viewer(): # Integration test for visualization service num_nodes = 3 num_items = 10 options = textworld.GameOptions() options.seeds = 1234 options.nb_rooms = num_nodes options.nb_objects = num_items options.quest_length = 3 options.grammar.theme = "house" options.grammar.include_adj = True game = textworld.generator.make_game(options) game_name = "test_html_viewer_wrapper" with make_temp_directory(prefix=game_name) as tmpdir: game_file = compile_game(game, path=tmpdir) env = textworld.start(game_file) env = HtmlViewer(env, open_automatically=False, port=8080) env.reset() # Cause rendering to occur. # options.binary_location = "/bin/chromium" driver = get_webdriver() driver.get("http://127.0.0.1:8080") nodes = driver.find_elements_by_class_name("node") assert len(nodes) == num_nodes items = driver.find_elements_by_class_name("item") objects = [obj for obj in game.world.objects if obj.type != "I"] assert len(items) == len(objects) env.close() driver.close()
def test_quest_winning_condition_go(): M = textworld.GameMaker() # R1 -- R2 -- R3 R1 = M.new_room("West room") R2 = M.new_room("Center room") R3 = M.new_room("East room") M.set_player(R1) M.connect(R1.east, R2.west) M.connect(R2.east, R3.west) M.set_quest_from_commands(["go east", "go east"]) game = M.build() game_name = "test_quest_winning_condition_go" with make_temp_directory(prefix=game_name) as tmpdir: game_file = compile_game(game, game_name, games_folder=tmpdir) env = textworld.start(game_file) env.reset() game_state, _, done = env.step("go east") assert not done assert not game_state.has_won game_state, _, done = env.step("go east") assert done assert game_state.has_won
def test_playing_a_game(): for ext in [".ulx", ".z8"]: with make_temp_directory(prefix="test_tw-play") as tmpdir: options = textworld.GameOptions() options.file_ext = ext options.path = tmpdir options.nb_rooms = 5 options.nb_objects = 10 options.quest_length = 5 options.quest_breadth = 2 options.seeds = 1234 game_file, _ = textworld.make(options) command = [ "tw-play", "--max-steps", "100", "--mode", "random", game_file ] assert check_call(command) == 0 command = [ "tw-play", "--max-steps", "100", "--mode", "random-cmd", game_file ] assert check_call(command) == 0 command = [ "tw-play", "--max-steps", "100", "--mode", "walkthrough", game_file ] assert check_call(command) == 0
def test_names_disambiguation(): M = textworld.GameMaker() room = M.new_room("room") M.set_player(room) apple = M.new(type="o", name="apple") orange = M.new(type="o", name="orange") tasty_apple = M.new(type="o", name="tasty apple") tasty_orange = M.new(type="o", name="tasty orange") room.add(apple, orange, tasty_apple, tasty_orange) game = M.build() game_name = "test_names_disambiguation" with make_temp_directory(prefix=game_name) as tmpdir: game_file = compile_game(game, game_name, games_folder=tmpdir) env = textworld.start(game_file) env.reset() game_state, _, done = env.step("take tasty apple") assert "tasty apple" in game_state.inventory game_state, _, done = env.step("take tasty orange") assert "tasty orange" in game_state.inventory env.reset() game_state, _, done = env.step("take orange") assert "tasty orange" not in game_state.inventory assert "orange" in game_state.inventory game_state, _, done = env.step("take tasty") assert "?" in game_state.feedback # Disambiguation question. game_state, _, done = env.step("apple") assert "tasty orange" not in game_state.inventory assert "tasty apple" in game_state.inventory assert "tasty apple" not in game_state.description
def record_quest(self, ask_for_state: bool = False) -> Quest: """ Defines the game's quest by recording the commands. This launches a `textworld.play` session. Args: ask_for_state: If true, the user will be asked to specify which set of facts of the final state are should be true in order to consider the quest as completed. Returns: The resulting quest. """ with make_temp_directory() as tmpdir: game_file = self.compile(pjoin(tmpdir, "record_quest")) recorder = Recorder() textworld.play(game_file, wrapper=recorder) # Skip "None" actions. actions = [action for action in recorder.actions if action is not None] # Ask the user which quests have important state, if this is set # (if not, we assume the last action contains all the relevant facts) winning_facts = None if ask_for_state and recorder.last_game_state is not None: winning_facts = user_query.query_for_important_facts(actions=recorder.actions, facts=recorder.last_game_state.state.facts, varinfos=self._working_game.infos) self._quests = [Quest(actions=actions, winning_conditions=winning_facts)] # Calling build will generate the description for the quest. self.build() return self._quests[0]
def test_batch_env(): batch_size = 4 max_episode_steps = 13 with make_temp_directory() as tmpdir: options = textworld.GameOptions() options.path = tmpdir options.seeds = 1234 options.file_ext = ".ulx" game_file1, game1 = textworld.make(options) options.seeds = 4321 options.file_ext = ".z8" game_file2, game2 = textworld.make(options) env_options = EnvInfos(inventory=True, description=True, admissible_commands=True) env_id = textworld.gym.register_games([game_file1, game_file1, game_file2, game_file2], request_infos=env_options, batch_size=batch_size, max_episode_steps=max_episode_steps, name="test-auto-reset", asynchronous=True, auto_reset=True) env = gym.make(env_id) env.reset() # env.close() del env print("OKAY")
def test_batch(): batch_size = 5 with make_temp_directory() as tmpdir: options = textworld.GameOptions() options.path = tmpdir options.seeds = 1234 gamefile, game = textworld.make(options) env_options = EnvInfos(inventory=True, description=True, admissible_commands=True) env_id = textworld.gym.register_games([gamefile], env_options, name="test-batch") env_id = textworld.gym.make_batch(env_id, batch_size) env = gym.make(env_id) obs, infos = env.reset() assert len(obs) == batch_size assert len(set(obs)) == 1 # All the same game. assert len(infos) == len(env_options) for values in infos.values(): assert len(values) == batch_size for cmd in game.main_quest.commands: obs, scores, dones, infos = env.step([cmd] * batch_size) env.close() assert all(dones) assert all(score == 1 for score in scores)
def test_html_viewer(): # Integration test for visualization service num_nodes = 3 num_items = 10 g_rng.set_seed(1234) grammar_flags = {"theme": "house", "include_adj": True} game = textworld.generator.make_game(world_size=num_nodes, nb_objects=num_items, quest_length=3, grammar_flags=grammar_flags) game_name = "test_html_viewer_wrapper" with make_temp_directory(prefix=game_name) as tmpdir: game_file = compile_game(game, game_name, games_folder=tmpdir) env = textworld.start(game_file) env = HtmlViewer(env, open_automatically=False, port=8080) env.reset() # Cause rendering to occur. # options.binary_location = "/bin/chromium" driver = get_webdriver() driver.get("http://127.0.0.1:8080") nodes = driver.find_elements_by_class_name("node") assert len(nodes) == num_nodes items = driver.find_elements_by_class_name("item") objects = [obj for obj in game.world.objects if obj.type != "I"] assert len(items) == len(objects) env.close() driver.close()
def test_third_party(): with make_temp_directory(prefix="test_tw-make_third_party") as tmpdir: challenge_py = pjoin(tmpdir, "my_challenge.py") with open(challenge_py, "w") as f: f.write( textwrap.dedent("""\ import argparse from typing import Mapping, Optional import textworld from textworld.challenges import register from textworld import Game, GameOptions def build_argparser(parser=None): parser = parser or argparse.ArgumentParser() group = parser.add_argument_group('This challenge settings') group.add_argument("--nb-locations", required=True, type=int, help="Number of locations in the game.") return parser def make_game(settings: Mapping[str, str], options: Optional[GameOptions] = None) -> Game: options = options or GameOptions options.nb_rooms = settings["nb_locations"] game = textworld.generator.make_game(options) return game # Register this new challenge. register(name="my-challenge", desc="Generate new challenge game", make=make_game, add_arguments=build_argparser) """)) NB_LOCATIONS = 3 output_folder = pjoin(tmpdir, "gen_games") game_file = pjoin(output_folder, "game_1234.ulx") command = [ "tw-make", "--third-party", challenge_py, "my-challenge", "--seed", "1234", "--output", game_file, "--silent" ] try: check_call(command) except CalledProcessError as e: assert e.returncode == 2 # Missing the --nb-locations argument. else: assert False, "tw-make should have failed." command += ["--nb-locations", str(NB_LOCATIONS)] assert check_call(command) == 0 game = textworld.Game.load(game_file.replace(".ulx", ".json")) assert len(game.world.rooms) == NB_LOCATIONS
def test(self) -> None: """ Test the game being built. This launches a `textworld.play` session. """ with make_temp_directory() as tmpdir: game_file = self.compile(pjoin(tmpdir, "test_game.ulx")) textworld.play(game_file)
def test_missing_game_infos_file(self): with make_temp_directory() as tmpdir: for ext, env_class in [(".ulx", GitGlulxEnv), (".z8", JerichoEnv)]: gamefile = pjoin(tmpdir, "tmp" + ext) with open(gamefile, "w"): pass # Empty file env = TWInform7(env_class()) npt.assert_raises(MissingGameInfosError, env.load, gamefile)
def test_extract_vocab_theme(): with make_temp_directory(prefix="test_extract_vocab_theme") as tmpdir: outfile = pjoin(tmpdir, "vocab.txt") command = [ "tw-extract", "vocab", "--theme", "house", "--output", outfile ] stdout = check_output(command).decode() assert os.path.isfile(outfile) assert int(re.findall(r"Found (\d+)", stdout)[0]) > 0
def set_quest_from_commands(self, commands: List[str], ask_for_state: bool = False) -> Quest: """ Defines the game's quest using predefined text commands. This launches a `textworld.play` session. Args: commands: Text commands. ask_for_state: If true, the user will be asked to specify which set of facts of the final state are should be true in order to consider the quest as completed. Returns: The resulting quest. """ with make_temp_directory() as tmpdir: try: game_file = self.compile(pjoin(tmpdir, "record_quest.ulx")) recorder = Recorder() agent = textworld.agents.WalkthroughAgent(commands) textworld.play(game_file, agent=agent, wrappers=[recorder], silent=True) except textworld.agents.WalkthroughDone: pass # Quest is done. # Skip "None" actions. actions = [action for action in recorder.actions if action is not None] # Ask the user which quests have important state, if this is set # (if not, we assume the last action contains all the relevant facts) winning_facts = None if ask_for_state and recorder.last_game_state is not None: winning_facts = [ user_query.query_for_important_facts( actions=recorder.actions, facts=recorder.last_game_state.state.facts, varinfos=self._working_game.infos) ] if len(commands) != len(actions): unrecognized_commands = [ c for c, a in zip(commands, recorder.actions) if a is None ] raise QuestError( "Some of the actions were unrecognized: {}".format( unrecognized_commands)) event = Event(actions=actions, conditions=winning_facts) self.quests = [Quest(win_events=[event])] # Calling build will generate the description for the quest. self.build() return self.quests[-1]
def test_quest_winning_condition(): g_rng.set_seed(2018) map_ = make_small_map(n_rooms=5, possible_door_states=["open"]) world = World.from_map(map_) def _rule_to_skip(rule): # Examine, look and inventory shouldn't be used for chaining. if rule.name.startswith("look"): return True if rule.name.startswith("inventory"): return True if rule.name.startswith("examine"): return True return False for rule in KnowledgeBase.default().rules.values(): if _rule_to_skip(rule): continue options = ChainingOptions() options.backward = True options.max_depth = 1 options.create_variables = True options.rules_per_depth = [[rule]] options.restricted_types = {"r"} chain = sample_quest(world.state, options) assert len(chain.actions) > 0, rule.name event = Event(chain.actions) quest = Quest(win_events=[event]) # Set the initial state required for the quest. tmp_world = World.from_facts(chain.initial_state.facts) game = make_game_with(tmp_world, [quest], make_grammar({})) if tmp_world.player_room is None: # Randomly place the player in the world since # the action doesn't care about where the player is. tmp_world.set_player_room() game_name = "test_quest_winning_condition_" + rule.name.replace( "/", "_") with make_temp_directory(prefix=game_name) as tmpdir: game_file = _compile_game(game, path=tmpdir) env = textworld.start(game_file) env.reset() game_state, _, done = env.step("look") assert not done assert not game_state.won game_state, _, done = env.step(event.commands[0]) assert done assert game_state.won
def test_game_with_infinite_max_score(): M = textworld.GameMaker() museum = M.new_room("Museum") statue = M.new(type="o", name="golden statue") pedestal = M.new(type="s", name="pedestal") pedestal.add(statue) museum.add(pedestal) M.set_player(museum) M.quests = [ Quest(win_events=[ Event(conditions=[M.new_fact('in', statue, M.inventory)]), ], reward=10, optional=True, repeatable=True), Quest(win_events=[ Event(conditions=[M.new_fact('at', statue, museum)]), ], reward=0) ] M.set_walkthrough(["take statue from pedestal", "look", "drop statue"]) game = M.build() game_name = "test_game_with_infinite_max_score" with make_temp_directory(prefix=game_name) as tmpdir: game_file = _compile_game(game, path=tmpdir) env = textworld.start(game_file) state = env.reset() state.max_score == np.inf # Score increases for each turn the player hold the statue. state, score, done = env.step("look") assert not done assert score == 0 state, score, done = env.step("take statue") assert score == 10 state, score, done = env.step("wait") assert score == 20 state, score, done = env.step("score") assert score == 20 assert "You have so far scored 20 points," in state.feedback state, score, done = env.step("wait") assert score == 30 state, score, done = env.step("drop statue") assert done assert score == 30 assert "a total of 30 points," in state.feedback
def test_play_generated_games(): NB_GAMES = 10 rng = np.random.RandomState(1234) for i in range(NB_GAMES): # Sample game specs. world_size = rng.randint(1, 10) nb_objects = rng.randint(0, 20) quest_length = rng.randint(1, 10) game_seed = rng.randint(0, 65365) grammar_flags = {} # Default grammar. with make_temp_directory(prefix="test_play_generated_games") as tmpdir: game_file, game = textworld.make(world_size, nb_objects, quest_length, grammar_flags, seed=game_seed, games_dir=tmpdir) # Solve the game using WalkthroughAgent. agent = textworld.agents.WalkthroughAgent() textworld.play(game_file, agent=agent, silent=True) # Play the game using RandomAgent and make sure we can always finish the # game by following the winning policy. env = textworld.start(game_file) agent = textworld.agents.RandomCommandAgent() agent.reset(env) env.compute_intermediate_reward() env.seed(4321) game_state = env.reset() max_steps = 100 reward = 0 done = False for step in range(max_steps): command = agent.act(game_state, reward, done) game_state, reward, done = env.step(command) if done: msg = "Finished before playing `max_steps` steps." if game_state.has_won: msg += " (winning)" assert game_state._game_progression.winning_policy == [] if game_state.has_lost: msg += " (losing)" assert game_state._game_progression.winning_policy is None print(msg) break # Make sure the game can still be solved. winning_policy = game_state._game_progression.winning_policy assert len(winning_policy) > 0 assert game_state.state.is_sequence_applicable(winning_policy)
def test_playing_generated_games(): NB_GAMES = 10 rng = np.random.RandomState(1234) for i in range(NB_GAMES): # Sample game specs. world_size = rng.randint(1, 10) nb_objects = rng.randint(0, 20) quest_depth = rng.randint(2, 5) quest_breadth = rng.randint(3, 7) game_seed = rng.randint(0, 65365) with make_temp_directory(prefix="test_play_generated_games") as tmpdir: options = textworld.GameOptions() options.path = tmpdir options.nb_rooms = world_size options.nb_objects = nb_objects options.chaining.max_depth = quest_depth options.chaining.max_breadth = quest_breadth options.seeds = game_seed game_file, game = textworld.make(options) # Solve the game using WalkthroughAgent. agent = textworld.agents.WalkthroughAgent() textworld.play(game_file, agent=agent, silent=True) # Play the game using RandomAgent and make sure we can always finish the # game by following the winning policy. env = textworld.start(game_file) env.infos.policy_commands = True env.infos.game = True agent = textworld.agents.RandomCommandAgent() agent.reset(env) env.seed(4321) game_state = env.reset() max_steps = 100 reward = 0 done = False for step in range(max_steps): command = agent.act(game_state, reward, done) game_state, reward, done = env.step(command) if done: assert game_state._winning_policy is None game_state, reward, done = env.reset(), 0, False # Make sure the game can still be solved. winning_policy = game_state._winning_policy assert len(winning_policy) > 0 assert game_state._game_progression.state.is_sequence_applicable( winning_policy)