Python Forum
Tutorial for making a "choose a path" game
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Tutorial for making a "choose a path" game
#2
You should check out my tutorial on text games. It talks about how creating a text adventure (like Zork) with an if-then structure (like your choose your own adventure) leads to problems down the line, and how text adventures can be done more easily by moving the if-then structure into data. The same holds true for the choose your own adventure situation.

Here's an example I wrote, based on Monty Python's argument sketch:

ARGUMENT = {'start': {'text': "You start the argument by noting that Star Wars is fantasy, not science-fiction. John replies that, no, it isn't",
        'choices': [('Yes it is.', 'yes-is'), ('Point out that Star Wars is just swords and sorcery.', 'yes-is')]},
    'yes-is': {'text': "John replies that, no, it isn't.",
        'choices': [('Yes it is.', 'yes-is'), ("Point out that's not actually arguing.", 'not-argue')]},
    'not-argue': {'text': "You point out that an argument is not the needless gainsaying of whatever is said to you. John replies that, yes, it is.",
        'choices': [("No it isn't", 'no-is'), ("Point out that he's doing it again.", 'again')]},
    'no-is': {'text': "John replies that, yes, it is.",
        'choices': [("No it isn't", 'no-is'), ("Point out that he's doing it again.", 'again')]},
    'again': {'text': "You point out that John is just needlessly gainsaying again. He replies that no, he isn't",
        'choices': [('Yes you are!', 'yes-are'), ("Point out that he's doing it again.", 'the-end')]},
    'yes-are': {'text': "John replies that, no, he isn't.",
        'choices': [('Yes you are!', 'yes-are'), ("Point out that he's doing it again.", 'the-end')]},
    'the-end': {'text': "Ding! I'm sorry, time's up."}}

def choose(choices):
    print('\nChoose one:')
    for choice_index, choice in enumerate(choices, start = 1):
        print('{}: {}'.format(choice_index, choice[0]))
    while True:
        choice = input('\nWhat is your choice? ')
        try:
            return choices[int(choice) - 1][1]
        except (IndexError, ValueError):
            print('That is not a valid choice.')

def play(adventure):
    page_name = 'start'
    while not page_name.endswith('-end'):
        page = adventure[page_name]
        print('')
        print(page['text'])
        page_name = choose(page['choices'])
    print('')
    print(adventure[page_name]['text'])
    print('\nThanks for playing!')

if __name__ == '__main__':
    play(ARGUMENT)
Our adventure is the ARGUMENT dictionary. The keys are the names of pages (this is just an internal identifier). The values are a 'page' dictionary. Each page dictionary contains the text of the page and the choices at the end of the page. The choices are done as list of tuples, each tuple containing the text of the choice displayed to the user, and the name of the page to go to if they make that choice.

I'm not sure I explained that clearly, so lets walk through the code. First we have the play function. It sets the page_name to 'start', a special page for the start of the adventure. Then it has a while loop that goes until you get to a page ending with '-end', another special type of page for an end to the adventure. Each time through the loop, it gets the game from the adventure provided, prints the text for that page, and then gets the next page_name from the choose function, using the current page's choices.

The choice function prints the text for each with a number for that choice. Then it gets a choice from the user, and tries to use that as an index to the list of choices to return the page name associated with that choice. It keeps asking until it gets a valid choice, using try/except to catch invalid answers.

Note that the data driven code is much simpler than the if/then driven code. That makes it less likely to have bugs, easier to maintain, and easier to expand with new features. This is also aided by having less repetition in the code. Also note that it is more flexible. There are loops in my adventure, where you can visit the same page more than once. That's very hard to implement in an if then structure. This code is also not limited in the number of choices you have. You could give them three, four, or even one choice. No choices would be a problem that would put you in an infinite loop.
Craig "Ichabod" O'Brien - xenomind.com
I wish you happiness.
Recommended Tutorials: BBCode, functions, classes, text adventures
Reply


Messages In This Thread
RE: Tutorial for making a "choose a path" game - by ichabod801 - May-25-2019, 11:29 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  [Ursina Engine] Ursina Engine – 3D Python Game Engine Tutorial MK_CodingSpace 0 6,632 Feb-10-2021, 03:16 AM
Last Post: MK_CodingSpace

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020