@Annonomus Penguin, @QPaysTaxes, and I are building an engine for easy creation of text-based adventure games, like Zork. The engine is still in its early stages of development, and the following code is my prototype. Here's the library code.cactus.pyclass MapPosition(object):        Describes data about a position on in the world    map. Contains the following data attributes.        name     - The name of the choice.        desc     - A description of the choice.        choices  - A dictionary of possible choices.        function - An (optional) function to be run.        def __init__(self, name, desc, choices, function=None):        self.name     = name        self.desc     = desc        self.choices  = choices        self.function = function    def print_choice(self):                Outputs certain data about the choice, e.g, description,        it's name, possible choices, etc.                if self.choices != {}:            print {0}: {1} Choices: {2}.format(                self.name,                self.desc,                ', '.join([key for key, value in self.choices.iteritems()])            )        else:            print {0}: {1}.format(                self.name,                self.desc            )    def run_function(self):                Run the attached function when the choice is chosen        by the user.                if self.function is not None:            self.function()class GameMap(object):        Describes data about a world map. Contains the    following data attributes.        map_data - A list containing MapPosition's        def __init__(self, map_data):        self.map_data = map_data    def find_start(self):                This iterates over the self.map_data list and finds        the starting choice.                for index, choice in enumerate(self.map_data):            if choice.name.lower() == start:                return index            else:                continue    def return_map(self):                Returns the map_data as a list.                return self.map_dataclass MainGame(object):        Describes data about the game itself. Contains    the following data attributes.        name        - The name of the game.        desc        - The intro text to be printed.        prompt      - The prompt to use during gameplay.        game_map    - A GameMap instance containing map data.        def __init__(self, name, desc, prompt, game_map):        self.name         = name        self.desc         = desc        self.prompt       = prompt        self.game_map     = game_map        self.map_data     = game_map.return_map()        self.start_index  = game_map.find_start()        self.map_position = self.start_index    def play_game(self):                Start playing the game. This function will find the        MapPosition element that has the name start. Do note,        user input is lowered, but a check is also done on non-        lowered input.                print self.name        print self.desc        while True:            current_position = self.map_data[self.map_position]            possible_choices = current_position.choices            current_position.print_choice()            current_position.run_function()            user_input = raw_input(self.prompt)            if user_input.lower() in possible_choices:                self.map_position = possible_choices[user_input.lower()]            elif user_input in possible_choices:                self.map_position = possible_choices[user_input]Before I show the example file, here's a small tutorial on how to create a small game.First off, create a GameMap instance. This instance will hold MapPosition instances stored in an list.GAME_MAP = cactus.GameMap([    # ...])Next, fill the list inside GameMap with MapPosition instances. A MapPosition instance contains the following data. A name for the position. (Note, any MapPosition with the name start will be the starting position for the game).A description of the position.Other possible MapPosition instances that the player can choose.An optional function to be run.cactus.MapPosition(    position name,    position description,    {        a choice: 1 # <-- References the index of another position.    }    function=a_func # <-- If no function is referenced, default is None.)Finally, an instance of MainGame is created with the following data.The name of the game.A description of the game.The prompt to be used in the game.The game map, and instance of GameMap.GAME = cactus.MainGame(    game name,    game description,    game prompt,    GAME_MAP)Finally, after all that has been done, call GAME.play_game(), and play your game.For those who also want a concrete example of a simple game, the following program demonstrates that.import cactusfrom sys import exitGAME_MAP = cactus.GameMap([    cactus.MapPosition(        Start,        Welcome to the test!,        {            left:  1,            right: 2,        }    ),    cactus.MapPosition(        Left,        You took the left path and lived!,        {},        function=exit    ),    cactus.MapPosition(        Right,        You took the right path and died!,        {},        function=exit    )])GAME = cactus.MainGame(    Test Game,    This is a simple test game! Yay!,    > ,    GAME_MAP)GAME.play_game()Finally, for those who are interested, here's the Official Cactus Discussion Chat Room, and here's the link to the official project on Github.
Cactus (Prototype) - A game engine for text-based adventure games
python;game;library;adventure game
else:    continueDoes nothing: remove it.lower or not lower: you must decideI suggest you decide: either all input is lowercased or it is kept as the original, the following is not a clean solution (you can understand it is not clean because you spelled it out in the docs).if user_input.lower() in possible_choices:    self.map_position = possible_choices[user_input.lower()]elif user_input in possible_choices:    self.map_position = possible_choices[user_input]