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_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
Exemple #3
0
def test_cannot_win_or_lose_a_quest_twice():
    g_rng.set_seed(2018)
    M = textworld.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 = textworld.start(game_file)

        # 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.lost
        assert not game_state.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.lost
        assert game_state.won
Exemple #4
0
def test_quest_with_multiple_winning_and_losing_conditions():
    g_rng.set_seed(2018)
    M = textworld.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 = textworld.start(game_file)

        # Failing - 1
        env.reset()
        game_state, _, done = env.step("eat carrot")
        assert done
        assert game_state.lost
        assert not game_state.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.lost
        assert not game_state.won

        # Failing - 1
        env.reset()
        game_state, _, done = env.step("eat lettuce")
        assert done
        assert not game_state.lost
        assert game_state.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.lost
        assert game_state.won
def test_optional_and_repeatable_quests():
    M = textworld.GameMaker()
    museum = M.new_room("Museum")

    weak_statue = M.new(type="o", name="ivory statue")
    normal_statue = M.new(type="o", name="stone statue")
    strong_statue = M.new(type="o", name="granite statue")

    museum.add(weak_statue)
    museum.add(normal_statue)
    museum.add(strong_statue)

    M.set_player(museum)

    M.quests = [
        Quest(win_events=[
            Event(conditions=[M.new_fact('in', weak_statue, M.inventory)]),
        ],
              reward=-10,
              optional=True,
              repeatable=True),
        Quest(win_events=[
            Event(conditions=[M.new_fact('in', normal_statue, M.inventory)]),
        ],
              reward=3,
              optional=True),
        Quest(
            win_events=[
                Event(
                    conditions=[M.new_fact('in', strong_statue, M.inventory)]),
            ],
            reward=5,
        )
    ]
    M.set_walkthrough(
        ["take ivory", "take stone", "drop ivory", "take granite"])

    game = M.build()
    game_name = "test_optional_and_repeatable_quests"
    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 == 8  # 5 (main quest) + 3 (optional quest)

        state, score, done = env.step("take ivory")
        assert not done
        assert score == -10

        state, score, done = env.step("look")
        assert score == -20

        state, score, done = env.step("take stone")
        assert not done
        assert score == -27  # -10 + 3

        state, score, done = env.step("drop ivory")
        assert score == -27

        state, score, done = env.step("take granite")
        assert done
        assert score == -22  # +5.
        assert "-22 out of a possible 8" in state.feedback