Text Adventure Tutorial - if structure to dictionary (2024)

So, you're new to Python, and you want to make a game. You figure you'll make a text adventure game, that won't be too hard. To get started, you just program four rooms in a two by two grid to move around in.

"""if_adventure.pyA text adventure using if/elif statements."""# intro/setupprint("Welcome to Ichabod's Text Adventure")current_room = 'empty'# game loopwhile True:# display room contentsprint()if current_room == 'empty':print('You are in an empty room.')print('The stone floors and walls and cold and damp.')elif current_room == 'temple':print('You are in a small temple.')print('There are three rows of benches facing a small statue.')elif current_room == 'torture':print('You are in a torture chamber.')print('There is a rack and an iron maiden against the wall')print('and some chains and thumbscrews on the floor.')elif current_room == 'bedroom':print('You are in a bedroom.')print('There is a large bed with black, silk sheets on it.')# get user inputcommand = input('\nWhat do you do? ').strip()# movementif command.lower() in ('n', 'north'):if current_room == 'empty':current_room = 'temple'elif current_room == 'bedroom':current_room = 'torture'else:print("You can't go that way.")elif command.lower() in ('s', 'south'):if current_room == 'temple':current_room = 'empty'elif current_room == 'torture':current_room = 'bedroom'else:print("You can't go that way.")elif command.lower() in ('e', 'east'):if current_room == 'empty':current_room = 'bedroom'elif current_room == 'temple':current_room = 'torture'else:print("You can't go that way.")elif command.lower() in ('w', 'west'):if current_room == 'bedroom':current_room = 'empty'elif current_room == 'torture':current_room = 'temple'else:print("You can't go that way.")# quit gameelif command.lower() in ('q', 'quit'):break# bad commandelse:print("I don't understand that command.")

It works, but it's not good. Why not? The main thing is that it's repetitive. You're doing the same programming over and over again. That's a bad idea in programming. The more you do the same thing over and over, the more you likely you are to create errors. It's also much harder to maintain. If you want to update the way it works, you have to update every repetition.

Think about it this way: the first version of Colossal Cave Adventure (the first text adventure game) had 66 rooms. Imagine what this code would look like with 66 rooms. It would be a mess.

Computers are much better at repeating things than humans are. When you find yourself programming the same thing repeatedly, you first thought should be "How can I program this once?" Functions are a good way to do this. Write the code once in a function, and then call the function repeatedly. certainly any sizable text adventure should use functions. But there's another technique that's useful here:

"""dict_adventure.pyA text adventure using a dictionary."""# data setuprooms = {'empty': {'name': 'an empty room', 'east': 'bedroom', 'north': 'temple','text': 'The stone floors and walls and cold and damp.'},'temple': {'name': 'a small temple', 'east': 'torture', 'south': 'empty','text': 'There are three rows of benches facing a small statue.'},'torture': {'name': 'a torture chamber', 'west': 'temple', 'south': 'bedroom','text': 'There is a rack and an iron maiden against the wall\nand some chains and thumbscrews on the floor.'},'bedroom': {'name': 'a bedroom', 'north': 'torture', 'west': 'empty','text': 'There is a large bed with black, silk sheets on it.'}}directions = ['north', 'south', 'east', 'west']current_room = rooms['empty']# game loopwhile True:# display current locationprint()print('You are in {}.'.format(current_room['name']))print(current_room['text'])# get user inputcommand = input('\nWhat do you do? ').strip()# movementif command in directions:if command in current_room:current_room = rooms[current_room[command]]else:# bad movementprint("You can't go that way.")# quit gameelif command.lower() in ('q', 'quit'):break# bad commandelse:print("I don't understand that command.")

Much more succinct. You have one set of code to show what room you're in, not one set for each room. You have one set of code for moving from room to room, not one set for each direction. That means it's a lot less code. The dictionary version has 39 lines of code, the if/elif version has 64. You can add a room to the dictionary version with two or three lines of code. Adding a room to the if/elif version takes at least eight lines of code. Back to Colossal Cave Adventure, that would be at least 592 lines of code for 66 rooms, 724 if they had an average of 3 exits each. Colossal Cave Adventure only had about 700 lines of code, and included things you could pick up, creatures you could fight, and points you could score.

How did I do this? I took the conditions and actions of the if/elif code and put them into a dictionary. In more general terms, I took the structure out of the code, and put it into the data. I looked at what the rooms had in common, which was what was repeated in the code. That became the structure (keys) of my dictionary object. Then the differences in the room became the values in the dictionary object. Then my code just needs to use the structure in the dictionary object to access the values, without either the structure or the values having to be part of the code.

You don't have to use a dictionary for this sort of thing, but dictionaries are vary handy for it. Even if you use a dictionary in your program, you don't have to hard code the dictionary in the program. You could store the values for the dictionary in a tab-delimited text file and load it into the dictionary at the start of the game. Once you get more experienced at programming and learn object-oriented programming, you'll see how well classes can be used for this sort of thing.

Note that I've mentioned several objects in the descriptions of the rooms. In a typical text-adventure game, you can move things around. Let's implement that with our dictionary version:

"""object_adventure.pyA text adventure with objects you can pick up and put down."""# data setuprooms = {'empty': {'name': 'an empty room', 'east': 'bedroom', 'north': 'temple', 'contents': [],'text': 'The stone floors and walls are cold and damp.'},'temple': {'name': 'a small temple', 'east': 'torture', 'south': 'empty', 'text': 'This seems to be a place of worship and deep contemplation.', 'contents': ['bench', 'bench', 'bench', 'statue']},'torture': {'name': 'a torture chamber', 'west': 'temple', 'south': 'bedroom', 'contents': ['chains', 'thumbscrews'],'text': 'There is a rack and an iron maiden against the wall\naand some dark stains on the floor.'},'bedroom': {'name': 'a bedroom', 'north': 'torture', 'west': 'empty', 'contents': ['sheets', 'bed'],'text': 'This is clearly a bedroom, but no one has slept\nhere in a long time.'}}directions = ['north', 'south', 'east', 'west']current_room = rooms['empty']carrying = []# game loopwhile True:# display current locationprint()print('You are in {}.'.format(current_room['name']))print(current_room['text'])# display movable objectsif current_room['contents']:print('In the room are: {}'.format(', '.join(current_room['contents'])))# get user inputcommand = input('\nWhat do you do? ').strip()# movementif command in directions:if command in current_room:current_room = rooms[current_room[command]]else:# bad movementprint("You can't go that way.")# quit gameelif command.lower() in ('q', 'quit'):break# gather objectselif command.lower().split()[0] == 'get':item = command.lower().split()[1]if item in current_room['contents']:current_room['contents'].remove(item)carrying.append(item)else:print("I don't see that here.")# get rid of objectselif command.lower().split()[0] == 'drop':item = command.lower().split()[1]if item in carrying:current_room['contents'].append(item)carrying.remove(item)else:print("You aren't carrying that.")# bad commandelse:print("I don't understand that command.")

With 21 lines of code, we've added contents for the rooms, a way to display the contents of the rooms, and get and drop commands for moving things around. This code is still shorter and simpler than the if/else version, and it does more.

Note that if you tried to add these features to the if/else version, you would have to add data on the rooms anyway. Otherwise you couldn't keep track of what objects where in which room.

Now you just need creatures to encounter and points to score, and you have a complete text adventure game. If you came up with a way to store the data in a text file, you could probably do it in less than 100 lines of code.

Text Adventure Tutorial - if structure to dictionary (2024)

References

Top Articles
Latest Posts
Article information

Author: Duncan Muller

Last Updated:

Views: 6376

Rating: 4.9 / 5 (79 voted)

Reviews: 86% of readers found this page helpful

Author information

Name: Duncan Muller

Birthday: 1997-01-13

Address: Apt. 505 914 Phillip Crossroad, O'Konborough, NV 62411

Phone: +8555305800947

Job: Construction Agent

Hobby: Shopping, Table tennis, Snowboarding, Rafting, Motor sports, Homebrewing, Taxidermy

Introduction: My name is Duncan Muller, I am a enchanting, good, gentle, modern, tasty, nice, elegant person who loves writing and wants to share my knowledge and understanding with you.