Beispiel #1
0
def generate_never_ending_game(args):
    g_rng.set_seed(args.seed)

    msg = "--max-steps {} --nb-objects {} --nb-rooms {} --quest-length {} --quest-breadth {} --seed {}"
    print(
        msg.format(args.max_steps, args.nb_objects, args.nb_rooms,
                   args.quest_length, args.quest_breadth, g_rng.seed))
    print("Generating game...")

    options = GameOptions()
    options.seeds = g_rng.seed
    options.nb_rooms = args.nb_rooms
    options.nb_objects = args.nb_objects
    options.quest_length = args.quest_length
    options.quest_breadth = args.quest_breadth

    game = tw_textlabs.generator.make_game(options)
    if args.no_quest:
        game.quests = []

    game_name = "neverending"
    path = pjoin(args.output, game_name + ".ulx")
    options = tw_textlabs.GameOptions()
    options.path = path
    options.force_recompile = True
    game_file = tw_textlabs.generator.compile_game(game, options)
    return game_file
Beispiel #2
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
Beispiel #3
0
    def test_generating_quests(self):
        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 max_depth in range(1, 3):
            for rule in KnowledgeBase.default().rules.values():
                if _rule_to_skip(rule):
                    continue

                options = ChainingOptions()
                options.backward = True
                options.max_depth = max_depth
                options.create_variables = True
                options.rules_per_depth = [[rule]]
                options.restricted_types = {"r"}
                chain = sample_quest(world.state, options)

                # Build the quest by providing the actions.
                actions = chain.actions
                assert len(actions) == max_depth, rule.name
                quest = Quest(win_events=[Event(actions)])
                tmp_world = World.from_facts(chain.initial_state.facts)

                state = tmp_world.state
                for action in actions:
                    assert not quest.is_winning(state)
                    state.apply(action)

                assert quest.is_winning(state)

                # Build the quest by only providing the winning conditions.
                quest = Quest(
                    win_events=[Event(conditions=actions[-1].postconditions)])
                tmp_world = World.from_facts(chain.initial_state.facts)

                state = tmp_world.state
                for action in actions:
                    assert not quest.is_winning(state)
                    state.apply(action)

                assert quest.is_winning(state)
Beispiel #4
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
Beispiel #5
0
def test_used_names_is_updated(verbose=False):
    # Make generation throughout the framework reproducible.
    g_rng.set_seed(1234)

    # Generate a map that's shape in a cross with room0 in the middle.
    P = Variable('P')
    r = Variable('r_0', 'r')
    k1 = Variable('k_1', 'k')
    k2 = Variable('k_2', 'k')
    c1 = Variable('c_1', 'c')
    c2 = Variable('c_2', 'c')
    facts = [
        Proposition('at', [P, r]),
        Proposition('at', [k1, r]),
        Proposition('at', [k2, r]),
        Proposition('at', [c1, r]),
        Proposition('at', [c2, r]),
        Proposition('match', [k1, c1]),
        Proposition('match', [k2, c2])
    ]
    world = World.from_facts(facts)
    world.set_player_room()  # Set start room to the middle one.
    world.populate_room(10,
                        world.player_room)  # Add objects to the starting room.

    # Generate the world representation.
    grammar = tw_textlabs.generator.make_grammar({},
                                                 rng=np.random.RandomState(42))
    for k, v in grammar.grammar.items():
        grammar.grammar[k] = v[:2]  # Force reusing variables.

    game = tw_textlabs.generator.make_game_with(world, [], grammar)
    for entity_infos in game.infos.values():
        if entity_infos.name is None:
            continue

        assert entity_infos.name in grammar.used_names
Beispiel #6
0
def test_blend_instructions(verbose=False):
    # Make generation throughout the framework reproducible.
    g_rng.set_seed(1234)

    M = tw_textlabs.GameMaker()
    r1 = M.new_room()
    r2 = M.new_room()
    M.set_player(r1)

    path = M.connect(r1.north, r2.south)
    path.door = M.new(type="d", name="door")
    M.add_fact("locked", path.door)
    key = M.new(type="k", name="key")
    M.add_fact("match", key, path.door)
    r1.add(key)

    quest = M.set_quest_from_commands([
        "take key", "unlock door with key", "open door", "go north",
        "close door", "lock door with key", "drop key"
    ])

    game = M.build()

    grammar1 = tw_textlabs.generator.make_grammar(
        {"blend_instructions": False}, rng=np.random.RandomState(42))

    grammar2 = tw_textlabs.generator.make_grammar(
        {"blend_instructions": True}, rng=np.random.RandomState(42))

    quest.desc = None
    game.change_grammar(grammar1)
    quest1 = quest.copy()
    quest.desc = None
    game.change_grammar(grammar2)
    quest2 = quest.copy()
    assert len(quest1.desc) > len(quest2.desc)
Beispiel #7
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
Beispiel #8
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
Beispiel #9
0
 def setUpClass(cls):
     g_rng.set_seed(201809)
     cls.game = build_test_game()
     cls.tmpdir = tempfile.mkdtemp()
     cls.game_file = _compile_game(cls.game, folder=cls.tmpdir)