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 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_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_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_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(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 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_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)
def test_making_a_game_using_basic_theme(): for i in range(10): # Try a few different games. 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", "--theme", "basic", "--seed", str(i), "--output", game_file, "--silent"] assert check_call(command) == 0 # Solve the game using WalkthroughAgent. agent = textworld.agents.WalkthroughAgent() textworld.play(game_file, agent=agent, silent=True)
def test_making_a_custom_game(): 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 = pjoin(output_folder, "game_1234.ulx") assert os.path.isfile(game_file) # Solve the game using WalkthroughAgent. agent = textworld.agents.WalkthroughAgent() textworld.play(game_file, agent=agent, silent=True)
def test(self, walkthrough: bool = False) -> 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")) agent = textworld.agents.HumanAgent(autocompletion=True) if walkthrough: agent = textworld.agents.WalkthroughAgent() textworld.play(game_file, agent=agent)
def test_making_challenge_game(): with make_temp_directory(prefix="test_tw-challenge") as tmpdir: for challenge in textworld.challenges.CHALLENGES: env_id = "tw-{}-level1".format(challenge) output_folder = pjoin(tmpdir, "gen_games") game_file = pjoin(output_folder, env_id + ".ulx") command = ["tw-make", "challenge", env_id, "--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)
def test_making_a_small_game(play_the_game=False): M = GameMaker() # Create a 'bedroom' room. R1 = M.new_room("bedroom") M.set_player(R1) # Add a second room to the east of R1. R2 = M.new_room() # Generated name path = M.connect(R1.east, R2.west) # Undirected path # Add a closed door between R1 and R2. door = M.new_door(path, name='glass door') door.add_property("locked") # Put a matching key for the door on R1's floor. key = M.new(type='k', name='rusty key') M.add_fact("match", key, door) R1.add(key) # Add a closed chest in R2. chest = M.new(type='c', name='chest') chest.add_property("closed") R2.add(chest) # Add a 3 random portable objects in the chest. objs = [M.new(type='o') for _ in range(3)] chest.add(*objs) # Add 3 food objects in the player's inventory. foods = [M.new(type='f') for _ in range(3)] M.inventory.add(*foods) ## Add 10 random objects scattered in the world. #M.populate(nb_objects=10) game = M.build() assert "GameMaker" in game.metadata["desc"] with make_temp_directory(prefix="test_making_a_small_game") as tmpdir: game_file = _compile_game(game, folder=tmpdir) if play_the_game: textworld.play(game_file)
def __init__(self, gamefile, ob_max_length, act_max_length, vocab=None, mode="word"): self.gamefile = gamefile self.game_env = textworld.play(gamefile) self.action_space = text_spaces.Char(max_length=act_max_length) self.observation_space = text_spaces.Char(max_length=ob_max_length, extra_vocab=[".", ",", "\n"])
def test_making_challenge_game(): settings = { "tw-treasure_hunter": ["--level", "1"], "tw-coin_collector": ["--level", "1"], } with make_temp_directory(prefix="test_tw-challenge") as tmpdir: for challenge in textworld.challenges.CHALLENGES: output_folder = pjoin(tmpdir, "gen_games") game_file = pjoin(output_folder, challenge + ".ulx") command = [ "tw-make", challenge, "--seed", "1234", "--output", game_file, "--silent" ] + settings[challenge] 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)
def set_quest_from_commands(self, commands: List[str]) -> Quest: """ Defines the game's quest using predefined text commands. This launches a `textworld.play` session. 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, 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] 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) self.quests = [Quest(win_events=[event])] # Calling build will generate the description for the quest. self.build() return self.quests[-1]
def test_making_challenge_game(): settings = { "tw-treasure_hunter": [["--level", "5"]], "tw-coin_collector": [["--level", "5"]], "tw-simple": [["--rewards", "dense", "--goal", "brief"]], "tw-cooking": [["--recipe", "2", "--take", "1", "--cook", "--split", "valid"], ["--recipe", "2", "--take", "1", "--cook", "--drop", "--split", "valid"]], } with make_temp_directory(prefix="test_tw-challenge") as tmpdir: for challenge in textworld.challenges.CHALLENGES: for i, params in enumerate(settings[challenge]): output_folder = pjoin(tmpdir, "gen_games") game_file = pjoin(output_folder, challenge + "_{}".format(i) + ".ulx") command = ["tw-make", challenge, "--seed", "1234", "--output", game_file, "--silent"] + params 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)
def record_quest(self) -> Quest: """ Defines the game's quest by recording the commands. This launches a `textworld.play` session. Returns: The resulting quest. """ with make_temp_directory() as tmpdir: game_file = self.compile(pjoin(tmpdir, "record_quest.ulx")) recorder = Recorder() agent = textworld.agents.HumanAgent(autocompletion=True) textworld.play(game_file, agent=agent, wrappers=[recorder]) # Skip "None" actions. actions = [action for action in recorder.actions if action is not None] # Assume the last action contains all the relevant facts about the winning condition. event = Event(actions=actions) self.quests.append(Quest(win_events=[event])) # Calling build will generate the description for the quest. self.build() return self.quests[-1]