Example #1
0
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 = tw_textlabs.agents.WalkthroughAgent()
        tw_textlabs.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 = tw_textlabs.agents.WalkthroughAgent()
        tw_textlabs.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 = tw_textlabs.agents.WalkthroughAgent()
        tw_textlabs.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 = tw_textlabs.agents.WalkthroughAgent()
        tw_textlabs.play(output_folder + ".ulx", agent=agent, silent=True)
Example #2
0
def test_quest_winning_condition_go():
    M = tw_textlabs.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, path=tmpdir)

        env = tw_textlabs.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
Example #3
0
def test_make_lab_game_from_level():
    seed = "3311063"
    level = 22
    with make_temp_directory(prefix="test_tw-make-lab") as tmpdir:
        output_folder = pjoin(tmpdir, "gen_games")
        game_file = pjoin(output_folder,
                          "challenge_game%d_%s.ulx" % (level, seed))
        command = [
            "tw-make-lab", "challenge", "--seed", seed, "--max_search_steps",
            "2000", "--output", game_file, "--challenge",
            "tw-lab_game-level%d" % (level)
        ]
        print(' '.join(command))
        try:
            assert check_call(command) == 0
        except CalledProcessError as e:
            print(e.output)

        assert os.path.isdir(output_folder)
        assert os.path.isfile(game_file)

        # Solve the game using WalkthroughAgent.
        print("Solving game")
        agent = tw_textlabs.agents.WalkthroughAgent()
        stats = tw_textlabs.play(game_file, agent=agent, silent=True)
        assert (stats['score'] == 1)
Example #4
0
def test_make_custom_lab_game():
    seed = "32423"
    with make_temp_directory(prefix="test_tw-make-lab") as tmpdir:
        output_folder = pjoin(tmpdir, "gen_games")
        game_file = pjoin(output_folder, "game_%s.ulx" % (seed))
        command = [
            "tw-make-lab", "custom", "--seed", seed, "--output", game_file,
            "--surface_mode", "medium", "--merge_serial_actions",
            "--merge_parallel_actions", "--max_quest_length", "13",
            "--max_search_steps", "2000", "--lab_config_path",
            str(fpath)
        ]
        print(' '.join(command))
        try:
            assert check_call(command) == 0
        except CalledProcessError as e:
            print(e.output)

        assert os.path.isdir(output_folder)
        assert os.path.isfile(game_file)

        # Solve the game using WalkthroughAgent.
        agent = tw_textlabs.agents.WalkthroughAgent()
        stats = tw_textlabs.play(game_file, agent=agent, silent=True)
        assert (stats['score'] == 1)
Example #5
0
def test_html_viewer():
    # Integration test for visualization service
    num_nodes = 3
    num_items = 10
    options = tw_textlabs.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 = tw_textlabs.generator.make_game(options)

    game_name = "test_html_viewer_wrapper"
    with make_temp_directory(prefix=game_name) as tmpdir:
        options.path = tmpdir
        game_file = compile_game(game, options)

        env = tw_textlabs.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()
Example #6
0
def test_playing_a_game():
    with make_temp_directory(prefix="test_tw-play") as tmpdir:
        options = tw_textlabs.GameOptions()
        options.path = tmpdir
        options.nb_rooms = 5
        options.nb_objects = 10
        options.quest_length = 5
        options.quest_breadth = 4
        options.seeds = 1234
        game_file, _ = tw_textlabs.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
Example #7
0
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, tw_textlabs.start, game_file)
Example #8
0
    def new_event_using_commands(self, commands: List[str]) -> Event:
        """ Creates a new event using predefined text commands.

        This launches a `tw_textlabs.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 = tw_textlabs.agents.WalkthroughAgent(commands)
                tw_textlabs.play(game_file,
                                 agent=agent,
                                 wrapper=recorder,
                                 silent=True)
            except tw_textlabs.agents.WalkthroughDone:
                pass  # Quest is done.

        # Skip "None" actions.
        actions = [action for action in recorder.actions if action is not None]
        event = Event(actions=actions)
        return event
Example #9
0
    def test(self) -> None:
        """ Test the game being built.

        This launches a `tw_textlabs.play` session.
        """
        with make_temp_directory() as tmpdir:
            game_file = self.compile(pjoin(tmpdir, "test_game.ulx"))
            tw_textlabs.play(game_file)
Example #10
0
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 = tw_textlabs.start(game_file)
            env.reset()
            game_state, _, done = env.step("look")
            assert not done
            assert not game_state.has_won

            game_state, _, done = env.step(event.commands[0])
            assert done
            assert game_state.has_won
Example #11
0
def test_take_all_and_variants():
    M = tw_textlabs.GameMaker()

    # Empty room.
    room = M.new_room("room")
    M.set_player(room)

    game = M.build()
    game_name = "test_take_all_and_variants"
    with make_temp_directory(prefix=game_name) as tmpdir:
        game_file = _compile_game(game, path=tmpdir)
        env = tw_textlabs.start(game_file)
        env.reset()

        variants_to_test = itertools.product(["take", "get", "pick up"],
                                             ["all", "everything", "each"])
        for command in variants_to_test:
            game_state, _, done = env.step(" ".join(command))
            assert game_state.feedback.strip(
            ) == "You have to be more specific!"

    # Multiple objects to take.
    red_ball = M.new(type="o", name="red ball")
    blue_ball = M.new(type="o", name="blue ball")
    room.add(red_ball, blue_ball)

    game = M.build()
    game_name = "test_take_all_and_variants2"
    with make_temp_directory(prefix=game_name) as tmpdir:
        game_file = _compile_game(game, path=tmpdir)
        env = tw_textlabs.start(game_file)
        env.enable_extra_info("inventory")
        env.reset()

        game_state, _, done = env.step("take all ball")
        assert "red ball:" in game_state.feedback
        assert "blue ball:" in game_state.feedback
        assert "red ball" in game_state.inventory
        assert "blue ball" in game_state.inventory
Example #12
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 `tw_textlabs.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 = tw_textlabs.agents.WalkthroughAgent(commands)
                tw_textlabs.play(game_file,
                                 agent=agent,
                                 wrapper=recorder,
                                 silent=True)
            except tw_textlabs.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)
            ]

        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 make_and_play_game(level, lab_game_options):
    game = make_game_from_level(level, lab_game_options)
    if game:
        with make_temp_directory(prefix="test_tw-make") as tmpdir:
            output_folder = Path(tmpdir) / "gen_games"
            game_file = output_folder / ("%s.ulx" % (game.metadata["uuid"]))
            lab_game_options.path = game_file
            game_file = tw_textlabs.generator.compile_game(
                game, lab_game_options)
            # Solve the game using WalkthroughAgent.
            agent = tw_textlabs.agents.WalkthroughAgent()
            stats = tw_textlabs.play(game_file, agent=agent, silent=True)
            game.metadata.update({'quest_desc': game.main_quest.desc})
            game.metadata.update(stats)
    return game
Example #14
0
def test_making_game_is_reproducible_with_seed():
    with make_temp_directory(prefix="test_render_wrapper") as tmpdir:
        options = tw_textlabs.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 = tw_textlabs.make(options)
        options2 = options.copy()
        game_file2, game2 = tw_textlabs.make(options2)
        assert game_file1 == game_file2
        assert game1 == game2
        # Make sure they are not the same Python objects.
        assert id(game1) != id(game2)
Example #15
0
def test_extract_entities():
    with make_temp_directory(prefix="test_tw-extract") as tmpdir:
        options = tw_textlabs.GameOptions()
        options.path = tmpdir
        options.nb_rooms = 5
        options.nb_objects = 10
        options.quest_length = 5
        options.quest_breadth = 4
        options.seeds = 1234
        game_file, _ = tw_textlabs.make(options)

        outfile = pjoin(tmpdir, "entities.txt")
        command = ["tw-extract", "entities", game_file, "--output", outfile]
        stdout = check_output(command).decode()
        assert os.path.isfile(outfile)
        nb_entities = len(open(outfile).readlines())
        assert "Extracted {}".format(nb_entities) in stdout
Example #16
0
def test_making_challenge_game():
    with make_temp_directory(prefix="test_tw-challenge") as tmpdir:
        for challenge in tw_textlabs.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 = tw_textlabs.agents.WalkthroughAgent()
            tw_textlabs.play(game_file, agent=agent, silent=True)
Example #17
0
def test_sample_quests():
    with make_temp_directory(prefix="test_sample_quests") as tmpdir:
        game_file = pjoin(tmpdir, "game.ulx")
        command = [
            "tw-make", "custom", "--seed", "20181004", "--output", game_file
        ]
        check_output(command).decode()

        script = pjoin(SCRIPTS_PATH, "sample_quests.py")
        command = [
            "python", script, "--nb-quests", "10", "--quest-length", "10",
            "--quest-breadth", "5", "--output", tmpdir, game_file
        ]
        stdout = check_output(command).decode()
        assert len(stdout) > 0
        assert os.path.isfile(pjoin(tmpdir, "sample_world.png"))
        assert os.path.isfile(pjoin(tmpdir, "sample_tree.svg"))
        assert os.path.isfile(pjoin(tmpdir, "sample_graph.svg"))
Example #18
0
def test_check_generated_game():
    NB_GAMES = 3
    script = pjoin(SCRIPTS_PATH, "check_generated_games.py")
    with make_temp_directory(prefix="test_check_generated_game") as tmpdir:
        for i in range(NB_GAMES):
            command = [
                "tw-make", "custom", "--seed",
                str(i), "--output", tmpdir
            ]
            check_output(command).decode()

        game_files = [
            pjoin(tmpdir, f) for f in os.listdir(tmpdir) if f.endswith(".ulx")
        ]
        assert len(game_files) == NB_GAMES
        command = ["python", script] + game_files
        stdout = check_output(command).decode()
        for file in game_files:
            assert "Testing " + file in stdout
Example #19
0
def test_logger():
    rng = np.random.RandomState(1234)
    game_logger = GameLogger()

    for _ in range(10):
        options = tw_textlabs.GameOptions()
        options.nb_rooms = 5
        options.nb_objects = 10
        options.quest_length = 3
        options.quest_breadth = 3
        options.seeds = rng.randint(65635)

        game = tw_textlabs.generator.make_game(options)
        game_logger.collect(game)

    with make_temp_directory(prefix="tw_textlabs_tests") as tests_folder:
        filename = pjoin(tests_folder, "game_logger.pkl")
        game_logger.save(filename)
        game_logger2 = GameLogger.load(filename)
        assert game_logger is not game_logger2
        assert game_logger.stats() == game_logger2.stats()
Example #20
0
def test_making_game_with_names_to_exclude():
    g_rng.set_seed(42)

    with make_temp_directory(prefix="test_render_wrapper") as tmpdir:
        options = tw_textlabs.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 = tw_textlabs.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 = tw_textlabs.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
Example #21
0
    def test_game_ended_when_no_quest(self):
        M = GameMaker()

        room = M.new_room()
        M.set_player(room)
        item = M.new(type="o")
        room.add(item)

        game = M.build()
        game_name = "test_game_ended_when_no_quest"
        with make_temp_directory(prefix=game_name) as tmpdir:
            options = tw_textlabs.GameOptions()
            options.path = tmpdir
            game_file = tw_textlabs.generator.compile_game(game, options)

            env = tw_textlabs.start(game_file)
            env.activate_state_tracking()
            game_state = env.reset()

            assert not game_state.game_ended
            game_state, _, done = env.step("look")
            assert not done
            assert not game_state.game_ended
Example #22
0
def test_making_a_game(play_the_game=False):
    rng_map = np.random.RandomState(1234)
    map_ = tw_textlabs.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(123)
    nb_objects = 10
    world.populate(nb_objects, rng=rng_objects)

    rng_quest = np.random.RandomState(124)
    quest = make_quest(world, quest_length=5, rng=rng_quest)

    # 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 = tw_textlabs.generator.make_grammar(grammar_flags,
                                                 rng=rng_grammar)

    # Generate the world representation.
    game = tw_textlabs.generator.make_game_with(world, [quest], grammar)

    with make_temp_directory(prefix="test_render_wrapper") as tmpdir:
        options = tw_textlabs.GameOptions()
        options.path = tmpdir
        game_file = compile_game(game, options)

        if play_the_game:
            tw_textlabs.play(game_file)
Example #23
0
def test_disambiguation_questions():
    M = tw_textlabs.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 = tw_textlabs.start(game_file)
        env.enable_extra_info("description")
        env.enable_extra_info("inventory")

        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
Example #24
0
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 = tw_textlabs.GameOptions()
            options.path = tmpdir
            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 = tw_textlabs.make(options)

            # Solve the game using WalkthroughAgent.
            agent = tw_textlabs.agents.WalkthroughAgent()
            tw_textlabs.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 = tw_textlabs.start(game_file)

            agent = tw_textlabs.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 game_state._game_progression.winning_policy is None

                    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)
Example #25
0
def test_names_disambiguation():
    M = tw_textlabs.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, path=tmpdir)
        env = tw_textlabs.start(game_file)
        env.enable_extra_info("description")
        env.enable_extra_info("inventory")
        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

    # Actions with two arguments.
    M = tw_textlabs.GameMaker()
    roomA = M.new_room("roomA")
    roomB = M.new_room("roomB")
    roomC = M.new_room("roomC")
    M.set_player(roomA)

    path = M.connect(roomA.east, roomB.west)
    gateway = M.new_door(path, name="gateway")

    path = M.connect(roomA.west, roomC.east)
    rectangular_gateway = M.new_door(path, name="rectangular gateway")

    keycard = M.new(type="k", name="keycard")
    rectangular_keycard = M.new(type="k", name="rectangular keycard")
    roomA.add(keycard, rectangular_keycard)

    M.add_fact("match", keycard, gateway)
    M.add_fact("match", rectangular_keycard, rectangular_gateway)
    M.add_fact("locked", gateway)
    M.add_fact("locked", rectangular_gateway)

    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 = tw_textlabs.start(game_file)
        env.enable_extra_info("description")
        env.enable_extra_info("inventory")
        env.reset()
        game_state, _, done = env.step("take keycard")
        assert "keycard" in game_state.inventory
        game_state, _, done = env.step(
            "take keycard")  # Already in your inventory.
        assert "rectangular keycard" not in game_state.inventory
        game_state, _, done = env.step("take rectangular keycard")
        assert "rectangular keycard" in game_state.inventory

        game_state, _, done = env.step(
            "unlock gateway with rectangular keycard")
        assert "That doesn't seem to fit the lock." in game_state.command_feedback
        game_state, _, done = env.step("unlock gateway with keycard")
        game_state, _, done = env.step("open gateway")
        game_state, _, done = env.step("go east")
        assert "-= Roomb =-" in game_state.description

        game_state, _, done = env.step("go west")
        game_state, _, done = env.step(
            "unlock rectangular gateway with keycard")
        assert "That doesn't seem to fit the lock." in game_state.command_feedback
        game_state, _, done = env.step(
            "unlock rectangular gateway with rectangular keycard")
        game_state, _, done = env.step("open rectangular gateway")
        game_state, _, done = env.step("go west")
        assert "-= Roomc =-" in game_state.description

    # Test invariance of the order in which ambiguous object names are defined.
    # First define "type G safe" then a "safe".
    M = tw_textlabs.GameMaker()
    garage = M.new_room("garage")
    M.set_player(garage)

    key = M.new(type="k", name="key")
    typeG_safe = M.new(type="c", name="type G safe")
    safe = M.new(type="c", name="safe")

    safe.add(key)
    garage.add(safe, typeG_safe)

    M.add_fact("open", safe)

    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 = tw_textlabs.start(game_file)
        env.enable_extra_info("inventory")
        game_state = env.reset()
        game_state, _, done = env.step("take key from safe")
        assert "key" in game_state.inventory

    # First define "safe" then "type G safe".
    M = tw_textlabs.GameMaker()
    garage = M.new_room("garage")
    M.set_player(garage)

    key = M.new(type="k", name="key")
    safe = M.new(type="c", name="safe")
    typeG_safe = M.new(type="c", name="type G safe")

    safe.add(key)
    garage.add(safe, typeG_safe)

    M.add_fact("open", safe)

    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 = tw_textlabs.start(game_file)
        env.enable_extra_info("inventory")
        game_state = env.reset()
        game_state, _, done = env.step("take key from safe")
        assert "key" in game_state.inventory
Example #26
0
def test_cannot_win_or_lose_a_quest_twice():
    g_rng.set_seed(2018)
    M = tw_textlabs.GameMaker()

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

    carrot = M.new(type='f', name='carrot')
    lettuce = M.new(type='f', name='lettuce')
    M.inventory.add(carrot)
    M.inventory.add(lettuce)

    # Add a closed chest in R2.
    chest = M.new(type='c', name='chest')
    chest.add_property("open")
    R2.add(chest)

    # The goals
    event_carrot_in_closed_chest = Event(conditions={
        M.new_fact("in", carrot, chest),
        M.new_fact("closed", chest)
    })
    event_drop_carrot_R1 = Event(conditions={M.new_fact("at", carrot, R1)})
    event_drop_carrot_R2 = Event(conditions={M.new_fact("at", carrot, R2)})

    quest1 = Quest(win_events=[event_carrot_in_closed_chest],
                   fail_events=[event_drop_carrot_R1, event_drop_carrot_R2])

    event_lettuce_in_closed_chest = Event(conditions={
        M.new_fact("in", lettuce, chest),
        M.new_fact("closed", chest)
    })
    event_drop_lettuce_R1 = Event(conditions={M.new_fact("at", lettuce, R1)})
    event_drop_lettuce_R2 = Event(conditions={M.new_fact("at", lettuce, R2)})

    quest2 = Quest(win_events=[event_lettuce_in_closed_chest],
                   fail_events=[event_drop_lettuce_R1, event_drop_lettuce_R2])

    M.quests = [quest1, quest2]
    game = M.build()

    game_name = "test_cannot_win_or_lose_a_quest_twice"
    with make_temp_directory(prefix=game_name) as tmpdir:
        game_file = _compile_game(game, path=tmpdir)

        env = tw_textlabs.start(game_file)
        # Make sure we do not rely on the quest progression to
        # determine if the game was lost.
        assert not env._compute_intermediate_reward

        # Complete quest1 then fail it.
        env.reset()
        game_state, score, done = env.step("go east")
        assert score == 0
        game_state, score, done = env.step("insert carrot into chest")
        assert score == 0
        game_state, score, done = env.step("close chest")
        assert score == 1
        assert not done
        game_state, score, done = env.step("open chest")

        # Re-completing quest1 doesn't award more points.
        game_state, score, done = env.step("close chest")
        assert score == 1
        assert not done

        game_state, score, done = env.step("open chest")
        game_state, score, done = env.step("take carrot from chest")
        game_state, score, done = env.step("drop carrot")
        assert score == 1
        assert not done

        # Then fail quest2.
        game_state, score, done = env.step("drop lettuce")
        assert done
        assert game_state.has_lost
        assert not game_state.has_won

        env.reset()
        game_state, score, done = env.step("go east")
        game_state, score, done = env.step("insert carrot into chest")
        game_state, score, done = env.step("insert lettuce into chest")
        game_state, score, done = env.step("close chest")
        assert score == 2
        assert done
        assert not game_state.has_lost
        assert game_state.has_won
Example #27
0
def test_quest_with_multiple_winning_and_losing_conditions():
    g_rng.set_seed(2018)
    M = tw_textlabs.GameMaker()

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

    carrot = M.new(type='f', name='carrot')
    lettuce = M.new(type='f', name='lettuce')
    M.inventory.add(carrot)
    M.inventory.add(lettuce)

    # Add a closed chest in R2.
    chest = M.new(type='c', name='chest')
    chest.add_property("open")
    R2.add(chest)

    # The goal
    quest = Quest(
        win_events=[
            Event(conditions={
                M.new_fact("in", carrot, chest),
                M.new_fact("closed", chest)
            }),
            Event(conditions={M.new_fact("eaten", lettuce)})
        ],
        fail_events=[
            Event(conditions={
                M.new_fact("in", lettuce, chest),
                M.new_fact("closed", chest)
            }),
            Event(conditions={M.new_fact("eaten", carrot)})
        ])
    M.quests = [quest]
    game = M.build()

    game_name = "test_quest_with_multiple_winning_and_losing_conditions"
    with make_temp_directory(prefix=game_name) as tmpdir:
        game_file = _compile_game(game, path=tmpdir)

        env = tw_textlabs.start(game_file)
        # Make sure we do not rely on the quest progression to
        # determine if the game was lost.
        assert not env._compute_intermediate_reward

        # Failing - 1
        env.reset()
        game_state, _, done = env.step("eat carrot")
        assert done
        assert game_state.has_lost
        assert not game_state.has_won

        # Failing - 2
        env.reset()
        game_state, _, done = env.step("go east")
        assert not done
        game_state, _, done = env.step("insert lettuce into chest")
        assert not done
        game_state, _, done = env.step("close chest")
        assert done
        assert game_state.has_lost
        assert not game_state.has_won

        # Failing - 1
        env.reset()
        game_state, _, done = env.step("eat lettuce")
        assert done
        assert not game_state.has_lost
        assert game_state.has_won

        # Winning - 2
        env.reset()
        game_state, _, done = env.step("go east")
        assert not done
        game_state, _, done = env.step("insert carrot into chest")
        assert not done
        game_state, _, done = env.step("close chest")
        assert done
        assert not game_state.has_lost
        assert game_state.has_won
Example #28
0
        mdesc = M.new_lab_entity('mdsc')
        lab.add(mdesc)
        quest_gen_options.ent_desc_map[mat.var.name].append(mdesc.var.name)

# Add operations and their descriptors
ent_type = 'tlq_op'
n_max_descs = quest_gen_options.max_descs_per_ent[ent_type]
ops = [M.new_tlq_op(dynamic_define=True) for i in range(n_ops)]
for op in ops:
    lab.add(op)
    n_descs = quest_gen_options.quest_rng.randint(0, (n_max_descs + 1))
    for j in range(n_descs):
        odesc = M.new_lab_entity('odsc')
        lab.add(odesc)
        quest_gen_options.ent_desc_map[op.var.name].append(odesc.var.name)

#oven = M.new_lab_entity('sa', name='oven')
#lab.add(oven)

quest = M.generate_quest_surface_pair(quest_gen_options)
game = M.build()
pg = ProcessGraph()
pg.from_tw_actions(quest.actions)
pg.draw()
with make_temp_directory(prefix="test_tw-make") as tmpdir:
    output_folder = Path(tmpdir) / "gen_games"
    game_file = Path(output_folder) / ("%s.ulx" % (lab_game_options.uuid))
    game_file = tw_textlabs.generator.compile_game(game, lab_game_options)
    # Solve the game using WalkthroughAgent.
#        test_game_walkthrough_agent(game_file)
Example #29
0
def compile_inform7_game(source: str,
                         output: str,
                         verbose: bool = False) -> None:
    with make_temp_directory(prefix="tmp_inform") as project_folder:
        filename, ext = os.path.splitext(output)
        story_filename = filename + ".ni"

        # Save story file.
        with open(story_filename, 'w') as f:
            f.write(source)

        # Create the file structure needed by Inform7.
        source_folder = pjoin(project_folder, "Source")
        build_folder = pjoin(project_folder, "Build")
        if not os.path.isdir(source_folder):
            os.makedirs(source_folder)

        shutil.copy(story_filename, pjoin(source_folder, "story.ni"))

        # Write mandatory uuid.txt file
        open(pjoin(project_folder, "uuid.txt"), 'w').close()

        # Build Inform7 -> Inform6 -> game
        INFORM_HOME = os.environ.get("INFORM_HOME", I7_DEFAULT_PATH)
        ni = pjoin(INFORM_HOME, "share", "inform7", "Compilers", "ni")
        i6 = pjoin(INFORM_HOME, "share", "inform7", "Compilers", "inform6")
        i7_internal = pjoin(INFORM_HOME, "share", "inform7", "Internal")

        # Compile story file.
        cmd = [
            ni, "--internal", i7_internal, "--format={}".format(ext),
            "--project", project_folder
        ]

        if verbose:
            print("Running: {}".format(" ".join(cmd)))

        try:
            stdout = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as exc:
            msg = ""
            msg += "\n-== ni =-\nFAIL: {}\n{}========\n".format(
                exc.returncode, exc.output.decode())
            msg += "*** Usually this means a compilation error.\n"
            if ext == ".z8":
                msg += "*** Maybe the game is too big for a .z8 file. Try using .ulx instead.\n"
            msg += "*** See {} for more information.\n".format(story_filename)
            raise CouldNotCompileGameError(msg)
        else:
            if verbose:
                print("-= ni =-\n{}========\n".format(stdout.decode()))

        # Compile inform6 code.
        i6_input_filename = pjoin(build_folder, "auto.inf")

        i6_options = "-"
        # i6_options += "k"  # Debug file, maybe useful to extract vocab?
        if str2bool(os.environ.get("TEXTWORLD_I6_DEBUG", False)):
            i6_options += "D"  # Debug mode, enables Inform7 testing commands.

        i6_options += "E2wS"
        i6_options += "G" if ext == ".ulx" else "v8"
        i6_options += "F0"  # Use extra memory rather than temporary files.
        cmd = [i6, i6_options, i6_input_filename, output]

        if verbose:
            print("Running: {}".format(" ".join(cmd)))

        try:
            stdout = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
        except subprocess.CalledProcessError as exc:
            msg = ""
            msg += "\n-= i6 =-\nFAIL: {}\n{}========\n".format(
                exc.returncode, exc.output.decode())
            msg += "*** Usually this means a compilation error.\n"
            if ext == ".z8":
                msg += "*** Maybe the game is too big for a .z8 file. Try using .ulx instead.\n"
            msg += "*** See {} for more information.\n".format(story_filename)
            raise CouldNotCompileGameError(msg)
        else:
            if verbose:
                print("-= i6 =-\n{}========\n".format(stdout.decode()))