def make_game()

in textworld/challenges/tw_coin_collector/coin_collector.py [0:0]


def make_game(mode: str, options: GameOptions) -> textworld.Game:
    """ Make a Coin Collector game.

    Arguments:
        mode: Mode for the game where

              * `'simple'`: the distractor rooms are only placed orthogonaly
                to the chain. This means moving off the optimal path leads
                immediately to a dead end.
              * `'random'`: the distractor rooms are randomly place along the
                chain. This means a player can wander for a while before
                reaching a dead end.
        options:
            For customizing the game generation (see
            :py:class:`textworld.GameOptions <textworld.generator.game.GameOptions>`
            for the list of available options).

            .. warning:: This challenge requires `options.grammar.allowed_variables_numbering` to be `True`.

    Returns:
        Generated game.
    """
    # Needed for games with a lot of rooms.
    assert options.grammar.allowed_variables_numbering

    if mode == "simple" and float(options.nb_rooms) / options.quest_length > 4:
        msg = ("Total number of rooms must be less than 4 * `quest_length` "
               "when distractor mode is 'simple'.")
        raise ValueError(msg)

    metadata = {}  # Collect infos for reproducibility.
    metadata["desc"] = "Coin Collector"
    metadata["mode"] = mode
    metadata["seeds"] = options.seeds
    metadata["world_size"] = options.nb_rooms
    metadata["quest_length"] = options.quest_length

    rngs = options.rngs
    rng_map = rngs['map']

    M = textworld.GameMaker(options)

    # Generate map.
    rooms = []
    walkthrough = []
    for i in range(options.quest_length):
        r = M.new_room()
        if i >= 1:
            # Connect it to the previous rooms.
            free_exits = [k for k, v in rooms[-1].exits.items() if v.dest is None]
            src_exit = rng_map.choice(free_exits)
            dest_exit = reverse_direction(src_exit)
            M.connect(rooms[-1].exits[src_exit], r.exits[dest_exit])
            walkthrough.append("go {}".format(src_exit))

        rooms.append(r)

    M.set_player(rooms[0])

    # Add a coin for the player to pick up.
    coin = M.new(type="o", name="coin")
    rooms[-1].add(coin)

    # Add distractor rooms, if needed.
    chain_of_rooms = list(rooms)
    while len(rooms) < options.nb_rooms:
        if mode == "random":
            src = rng_map.choice(rooms)
        else:
            # Add one distractor room per room along the chain.
            src = chain_of_rooms[len(rooms) % len(chain_of_rooms)]

        free_exits = [k for k, v in src.exits.items() if v.dest is None]
        if len(free_exits) == 0:
            continue

        dest = M.new_room()
        src_exit = rng_map.choice(free_exits)
        dest_exit = reverse_direction(src_exit)
        M.connect(src.exits[src_exit], dest.exits[dest_exit])
        rooms.append(dest)

    # Generate the quest thats by collecting the coin.
    quest = Quest(win_events=[
        Event(conditions={M.new_fact("in", coin, M.inventory)})
    ])

    M.quests = [quest]

    walkthrough.append("take coin")
    M.set_walkthrough(walkthrough)

    game = M.build()
    game.metadata.update(metadata)
    mode_choice = 0 if mode == "simple" else 1
    uuid = "tw-coin_collector-{specs}-{grammar}-{seeds}"
    uuid = uuid.format(specs=encode_seeds((mode_choice, options.nb_rooms, options.quest_length)),
                       grammar=options.grammar.uuid,
                       seeds=encode_seeds([options.seeds[k] for k in sorted(options.seeds)]))
    game.metadata["uuid"] = uuid
    return game