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_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_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 setUpClass(cls): cls.tmpdir = pjoin(tempfile.mkdtemp(prefix="test_textworld"), "") options = textworld.GameOptions() options.path = cls.tmpdir options.nb_rooms = 5 options.nb_objects = 10 options.quest_length = 10 options.seeds = 1234 cls.game_file, cls.game = textworld.make(options) options.file_ext = ".z8" cls.game_file_z8, _ = textworld.make(options)
def setUpClass(cls): cls.tmpdir = pjoin(tempfile.mkdtemp(prefix="test_textworld_gym"), "") options = textworld.GameOptions() options.path = cls.tmpdir options.seeds = 1234 cls.gamefile1, cls.game1 = textworld.make(options) options.seeds = 4321 cls.gamefile2, cls.game2 = textworld.make(options) options.file_ext = ".z8" options.seeds = 1234 cls.gamefile1_z8, _ = textworld.make(options)
def setUpClass(cls): cls.tmpdir = pjoin(tempfile.mkdtemp(prefix="test_tw_extract"), "") options = textworld.GameOptions() options.path = cls.tmpdir options.nb_rooms = 5 options.nb_objects = 10 options.quest_length = 5 options.quest_breadth = 2 options.seeds = 1234 cls.game_file1, cls.game1 = textworld.make(options) options.seeds = 12345 options.file_ext = ".z8" cls.game_file2, cls.game2 = textworld.make(options)
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_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_making_game_is_reproducible_with_seed(): with make_temp_directory(prefix="test_render_wrapper") as tmpdir: options = textworld.GameOptions() options.nb_rooms = 2 options.nb_objects = 20 options.quest_length = 3 options.quest_breadth = 3 options.seeds = 123 game_file1, game1 = textworld.make(options, path=tmpdir) options2 = options.copy() game_file2, game2 = textworld.make(options2, path=tmpdir) assert game_file1 == game_file2 assert game1 == game2 # Make sure they are not the same Python objects. assert id(game1) != id(game2)
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_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 setUp(self): self.tmpdir = tempfile.mkdtemp(prefix="test_textworld") options = textworld.GameOptions() options.nb_rooms = 5 options.nb_objects = 10 options.quest_length = 10 options.seeds = 1234 self.game_file, self.game = textworld.make(options, path=self.tmpdir)
def setUp(self): self.tmpdir = tempfile.mkdtemp(prefix="test_textworld") self.game_file, self.game = textworld.make(world_size=5, nb_objects=10, quest_length=10, grammar_flags={}, seed=1234, games_dir=self.tmpdir)
def test_making_game_is_reproducible_with_seed(): grammar_flags = {} with make_temp_directory(prefix="test_render_wrapper") as tmpdir: game_file1, game1 = textworld.make(2, 20, 3, grammar_flags, seed=123, games_dir=tmpdir) game_file2, game2 = textworld.make(2, 20, 3, grammar_flags, seed=123, games_dir=tmpdir) assert game_file1 == game_file2 assert game1 == game2 # Make sure they are not the same Python objects. assert id(game1) != id(game2)
def test_making_game_with_names_to_exclude(): g_rng.set_seed(42) with make_temp_directory(prefix="test_render_wrapper") as tmpdir: options = textworld.GameOptions() options.path = tmpdir options.nb_rooms = 2 options.nb_objects = 20 options.quest_length = 3 options.quest_breadth = 3 options.seeds = 123 game_file1, game1 = textworld.make(options) options2 = options.copy() game1_objects_names = [info.name for info in game1.infos.values() if info.name is not None] options2.grammar.names_to_exclude = game1_objects_names game_file2, game2 = textworld.make(options2) 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_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_extract_vocab(): with make_temp_directory(prefix="test_extract_vocab") as tmpdir: options = textworld.GameOptions() options.path = tmpdir options.nb_rooms = 5 options.nb_objects = 10 options.quest_length = 5 options.quest_breadth = 2 options.seeds = 1234 game_file1, _ = textworld.make(options) options.seeds = 12345 game_file2, _ = textworld.make(options) outfile = pjoin(tmpdir, "vocab.txt") command = [ "tw-extract", "vocab", game_file1, game_file2, "--output", outfile ] stdout = check_output(command).decode() assert os.path.isfile(outfile) nb_words = len(open(outfile).readlines()) assert "Found {}".format(nb_words) in stdout
def test_register_games(): with make_temp_directory() as tmpdir: options = textworld.GameOptions() options.path = tmpdir options.seeds = 1234 gamefile1, game1 = textworld.make(options) options.seeds = 4321 gamefile2, game2 = textworld.make(options) env_options = EnvInfos(inventory=True, description=True, admissible_commands=True) env_id = textworld.gym.register_games([gamefile1, gamefile2], env_options, name="test-multi") env = gym.make(env_id) env.seed(2) # Make game2 starts on the first reset call. obs, infos = env.reset() assert len(infos) == len(env_options) for cmd in game2.main_quest.commands: obs, score, done, infos = env.step(cmd) assert done assert score == 1 obs, infos = env.reset() assert len(infos) == len(env_options) for cmd in game1.main_quest.commands: obs, score, done, infos = env.step(cmd) assert done assert score == 1 obs1, infos = env.reset() obs2, infos = env.reset() assert obs1 != obs2
def test_register_game(): 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, extras=["walkthrough"]) env_id = textworld.gym.register_game(gamefile, env_options, name="test-single") env = gym.make(env_id) obs, infos = env.reset() assert len(infos) == len(env_options) for cmd in infos.get("extra.walkthrough"): obs, score, done, infos = env.step(cmd) assert done assert score == 1
def test_making_a_custom_game(): with make_temp_directory(prefix="test_tw-play") as tmpdir: game_file, _ = textworld.make(5, 10, 5, {}, seed=1234, games_dir=tmpdir) 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_register_zmachine_game(): 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 existing Z-Machine game. env_options = EnvInfos() 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.main_quest.commands: obs, score, done, infos = env.step(cmd) assert done assert score == 1
def main(): args = parse_args() if args.very_verbose: args.verbose = args.very_verbose warnings.simplefilter("default", textworld.TextworldGenerationWarning) if args.seed is None: args.seed = np.random.randint(65635) print("Random seed: {}".format(args.seed)) rng = np.random.RandomState(args.seed) options = textworld.GameOptions() options.grammar.theme = args.theme options.grammar.include_adj = args.include_adj options.grammar.only_last_action = args.only_last_action options.grammar.blend_instructions = args.blend_instructions options.grammar.blend_descriptions = args.blend_descriptions options.grammar.ambiguous_instructions = args.ambiguous_instructions options.nb_rooms = args.world_size options.nb_objects = args.nb_objects options.quest_length = args.quest_length options.quest_breadth = args.quest_breadth agent = make_agent(args) reward_history = [] for i in range(args.nb_games) if args.nb_games > 0 else itertools.count(): options = options.copy() options.seeds = rng.randint(65635) game_file, game = textworld.make(options, args.output) print("Starting game {}".format(game_file)) env = textworld.start(game_file) agent.reset(env) if args.vizu >= 0: from textworld.envs.wrappers import HtmlViewer env = HtmlViewer(env, port=args.vizu) game_state = env.reset() if args.mode == "human" or args.verbose: env.render() reward = 0 done = False for t in range( args.max_steps) if args.max_steps > 0 else itertools.count(): command = agent.act(game_state, reward, done) game_state, reward, done = env.step(command) if args.mode == "human" or args.verbose: env.render() if done: break env.close() print("Done after {} steps. Score {}/{}.".format( game_state.nb_moves, game_state.score, game_state.max_score)) reward_history.append(reward) if args.nb_games == 0: # Interactive mode. input("Press enter to generate a new game.")
def main(): args = parse_args() if args.very_verbose: args.verbose = args.very_verbose warnings.simplefilter("default", textworld.TextworldGenerationWarning) if args.seed is None: args.seed = np.random.randint(65635) grammar_flags = { "theme": args.theme, "include_adj": args.include_adj, "only_last_action": args.only_last_action, "blend_instructions": args.blend_instructions, "blend_descriptions": args.blend_descriptions, "ambiguous_instructions": args.ambiguous_instructions } print("Random seed: {}".format(args.seed)) rng = np.random.RandomState(args.seed) agent = make_agent(args) reward_history = [] for i in range(args.nb_games) if args.nb_games > 0 else itertools.count(): # Get a game seed to make everything reproducible. game_seed = rng.randint(65635) game_file, game = textworld.make(args.world_size, args.nb_objects, args.quest_length, grammar_flags, seed=game_seed, games_dir=args.output) print("Starting game {}".format(game_file)) env = textworld.start(game_file, backend=args.backend) agent.reset(env) if args.vizu >= 0: from textworld.envs.wrappers import HtmlViewer env = HtmlViewer(env, port=args.vizu) game_state = env.reset() if args.mode == "human" or args.verbose: env.render() reward = 0 done = False for t in range( args.max_steps) if args.max_steps > 0 else itertools.count(): command = agent.act(game_state, reward, done) game_state, reward, done = env.step(command) if args.mode == "human" or args.verbose: env.render() if done: break env.close() print("Done after {} steps. Score {}/{}.".format( game_state.nb_moves, game_state.score, game_state.max_score)) reward_history.append(reward) if args.nb_games == 0: # Interactive mode. input("Press enter to generate a new game.")
from textworld.envs import FrotzEnvironment import textworld options = textworld.GameOptions() options.seeds = 1234 options.nb_objects = 5 options.quest_length = 2 game_file, _ = textworld.make(options) env = textworld.start(game_file) game_state = env.reset() env.render() command = "open door" game_state, reward, done = env.step(command) env.render()