Part 2: Go places
Contents
Part 2: Go places#
In this section we’ll be writing the go
command, and the system to go from
one place to another.
To start out we’ll add just two places: "home"
and the "town-square"
. A map
of the game world would look something like this:
You are welcome to add your own places. However, I strongly recommend that you
first get your go
command working with these two places.
You also may want to keep a map of the game world in a docstring or another text file. Here’s an example of how you might represent a slightly more populated world.
1"""
2Text-based adventure game
3https://alissa-huskey.github.io/python-class/exercises/adventure.html
4
5 =========
6 World Map
7 =========
8
9 market
10 |
11 home -- town square -- woods -- hill
12 | |
13 bakery cave
14
15"""
Part 2.1: Split reply into command and arguments#
This will be the first command that we’ve written that takes an argument. That
is, the player needs to type not just go
, but also which direction to go like
north
.
That means we need to split the string that is returned from input()
into a
list. That way we if the player types go north
we can figure out that go
is
the command, and north
is the direction.
Demo
A. Define do_go()
#
[ ]
Define ado_go()
function that takes one argument:args
.[ ]
Indo_go()
printTrying to go: args
B. In main()
, in the while loop#
[ ]
Strip the value returned frominput()
using the.strip()
method.This means if a player enters
" quit"
or"quit "
the program still knows to calldo_quit()
.[ ]
Call.split()
onreply
and assign it to the variableargs
.Now the
args
variable will contain a list where each word is an item in the list.[ ]
Use anif
statement to check ifargs
is falsy. If it is,continue
.This means that if a player doesn’t enter anything, the program will ignore it and start the loop over.
[ ]
Remove the first item fromargs
using the.pop()
method and assign it to the variablecommand
.Now
command
will contain the first word the player entered, andargs
will contain a list of the remaining commands. If there were no additional words, thenargs
will be an empty list.[ ]
In each clause of theif
statement where we check the value ofreply
, change it tocommand
.[ ]
Add anelif
clause that checks ifcommand
is equal to"g"
or"go"
. If it is, calldo_go()
and passargs
.
Code
1"""
2Text-based adventure game
3https://alissa-huskey.github.io/python-class/exercises/adventure.html
4"""
5
6ITEMS = {
7 "elixir": {
8 "key": "elixir",
9 "name": "healing elixir",
10 "description": "a magical elixir that will heal what ails ya",
11 "price": -10,
12 },
13 "dagger": {
14 "key": "dagger",
15 "name": "a dagger",
16 "description": "a 14 inch dagger with a double-edged blade",
17 "price": -25,
18 }
19}
20
21def do_shop():
22 """List the items for sale."""
23 print("\nItems for sale.\n")
24
25 for item in ITEMS.values():
26 print(f'{item["name"]:<13} {item["description"]}')
27
28 print()
29
30def do_quit():
31 """Exit the game."""
32 print("Ok, goodbye.")
33 quit()
34
35def do_go(args):
36 """Move to a different place"""
37 print(f"Trying to go: {args}")
38
39def main():
40 print("Welcome!")
41 while True:
42 reply = input("> ").strip()
43 args = reply.split()
44
45 if not args:
46 continue
47
48 command = args.pop(0)
49
50 if command in ["q", "quit", "exit"]:
51 do_quit()
52
53 elif command in ["shop"]:
54 do_shop()
55
56 elif command in ["g", "go"]:
57 do_go(args)
58
59 else:
60 print("No such command.")
61 continue
62
63 print()
64
65if __name__ == "__main__":
66 main()
67
Part 2.2: Create PLAYER
and PLACES
#
Now we’ll make global PLACES
dictionary which will store information about
the different areas in the game.
Like the ITEMS
dictionary, PLACES
will be a nested dictionary, where the
key is a unique identifier for each place, and the value is a dictionary with
detailed information about that place.
The keys of the child dictionary will be:
"key"
– the same thing as the key"name"
– a short description"description"
– a longer description"east"
,"west"
,"north"
,"south"
– the key to the place in that direction. (More on that next.)
Here is an example:
PLACES = {
"home": {
"key": "home",
"name": "Your Cottage",
"east": "town-square",
"description": "A cozy stone cottage with a desk and a neatly made bed.",
},
}
The "north"
, "south"
, "east"
and "west"
values will be used to tell
which way the player can go from a particular place and what is in that
direction.
For example, going "east"
from "home"
is the "town-square"
.
PLACES = {
"home": {
"key": "home",
"name": "Your Cottage",
"east": "town-square",
...
},
"town-square": {
"key": "town-square",
"name": "The Town Square",
"west": "home",
...
},
}
PLACES = {
"home": {
"key": "home",
"name": "Your Cottage",
"east": "town-square",
...
},
"town-square": {
"key": "town-square",
"name": "The Town Square",
"west": "home",
...
},
}
Likewise, going "west"
from the "town-square"
is "home"
.
PLACES = {
"home": {
"key": "home",
"name": "Your Cottage",
"east": "town-square",
...
},
"town-square": {
"key": "town-square",
"name": "The Town Square",
"west": "home",
...
},
}
PLACES = {
"home": {
"key": "home",
"name": "Your Cottage",
"east": "town-square",
...
},
"town-square": {
"key": "town-square",
"name": "The Town Square",
"west": "home",
...
},
}
We’ll also make a global PLAYER
dictionary that will save information about
the current game.
For now it will just have one key, the place
, which point to where the player
is at. In the do_go()
function, we will change that value to move the player
from one place to another.
PLAYER = {
"place": "home",
}
PLACES = {
"home": {
"key": "home",
"name": "Your Cottage",
"east": "town-square",
...
},
...
}
A. At the top of adventure.py
#
[ ]
Create aPLAYER
dictionary with the key"place"
and the value"home"
.[ ]
Create aPLACES
dictionary where the key is a unique identifier for each place. The value is a dictionary that with information about each place:"key"
– the same thing as the key"name"
– a short description"description"
– a longer description"east"
,"west"
,"north"
,"south"
– the key to the place in that
Add two places,
"home"
and"town-square"
.
Code
1"""
2Text-based adventure game
3https://alissa-huskey.github.io/python-class/exercises/adventure.html
4"""
5
6PLAYER = {
7 "place": "home",
8}
9
10PLACES = {
11 "home": {
12 "key": "home",
13 "name": "Your Cottage",
14 "east": "town-square",
15 "description": "A cozy stone cottage with a desk and a neatly made bed.",
16 },
17 "town-square": {
18 "key": "town-square",
19 "name": "The Town Square",
20 "west": "home",
21 "description": (
22 "A large open space surrounded by buildings with a burbling "
23 "fountain in the center."
24 ),
25 },
26}
27
28ITEMS = {
Part 2.3: Write message functions#
We’re going to take a brief interlude here to write a couple of functions for printing messages to the player.
We’ll add a debug()
function which will print messages intended for us (the
programmer), but only if a global variable indicates that the program is in
debug mode.
We’ll also add a error()
function which will print an error message.
Demo
A. At the top of adventure.py
#
[ ]
Add a global variableDEBUG
and set it toTrue
Code
1"""
2Text-based adventure game
3https://alissa-huskey.github.io/python-class/exercises/adventure.html
4"""
5
6DEBUG = True
7
8PLAYER = {
9 "place": "home",
10}
11
B. Define debug()
#
[ ]
Write a function named:debug
with one parameter:message
[ ]
In the function, check ifDEBUG
isTrue
(or truthy)[ ]
If so, then printmessage
[ ]
Bonus: Print something before it like"DEBUG: "
, or"# "
, so you can more easily tell that it is a debug message
Code
1def debug(message):
2 """Print a debug message if in debug mode."""
3 if not DEBUG:
4 return
5 print(f"# {message}")
C. Define error()
#
[ ]
Write a function named:error
with one parameter:message
[ ]
Printmessage
with something before it like"Error: "
.
Code
1def error(message):
2 """Print an error message."""
3 print(f"! Error: {message}\n")
D. Modify do_go()
#
[ ]
Calldebug()
instead ofprint()
for the messageTrying to go: args
Code
69def do_go(args):
70 """Move to a different place"""
71 debug(f"Trying to go: {args}")
E. In main()
, in the while loop#
[ ]
At the beginning of thewhile
loop calldebug()
with the messageYou are at: PLACE
. ReplacePLACE
with the value in thePLAYER
dictionary associated with the"place"
keyThis will print a debug message with your current location every time the loop runs.
[ ]
After assigningcommand
, usedebug()
to printcommand
andargs
.[ ]
Callerror()
instead ofprint()
for the messageNo such command.
Code
73def main():
74 print("Welcome!")
75
76 while True:
77 debug(f"You are at: {PLAYER['place']}")
78
79 reply = input("> ").strip()
80 args = reply.split()
81
82 if not args:
83 continue
84
85 command = args.pop(0)
86 debug(f"Command: {command!r}, args: {args!r}")
87
88 if command in ["q", "quit", "exit"]:
89 do_quit()
90
91 elif command in ["shop"]:
92 do_shop()
93
94 elif command in ["g", "go"]:
95 do_go(args)
96
97 else:
98 error("No such command.")
99 continue
100
101 print()
F. Test debug messages#
[ ]
Test withDEBUG
set toTrue
as well as withDEBUG
set toFalse
Part 2.4: Fill in go
command#
In this section we’ll be filling in the rest of the go
command.
We’ll need to make sure that we get a valid direction in args
. Then look up
where we are now from PLAYER["place"]
and PLACES
; and look up where we want
to go by looking at direction (ie "east"
) key in the current place dictionary.
Finally, we’ll change the current "place"
in the PLAYER
dictionary, and
print the "name"
and "description"
.
Demo
A. Modify do_go()
: ensure that the player typed a valid direction#
In this section we’ll be making sure there is at least one item in the args
list and that it is a valid direction.
[ ]
Check to see ifargs
is falsy, if so:[ ]
Use theerror()
function to print a message saying:"Which way do you want to go?"
[ ]
return
[ ]
assign the first item of theargs
list to the variabledirection
and make it lowercase[ ]
Check ifdirection
is one of"north"
,"south"
,"east"
,"west"
. If not:[ ]
Use theerror()
function to print a message saying:"Sorry, I don't know how to go: direction.")
[ ]
return
Code
69def do_go(args):
70 """Move to a different place"""
71 debug(f"Trying to go: {args}")
72
73 # make sure the player included a direction
74 if not args:
75 error("Which way do you want to go?")
76 return
77
78 # get the direction from arguments
79 # and make it lowercase
80 direction = args[0].lower()
81
82 # make sure it's a valid direction
83 if direction not in ('north', 'south', 'east', 'west'):
84 error(f"Sorry, I don't know how to go: {direction}.")
85 return
B. Modify do_go()
: look up where the player is at#
In this section we’ll be using the PLAYER["place"]
to get the current place
from the PLACES
dictionary, as shown here.
[ ]
get the value fromPLAYER
associated with the"place"
key and assign it toold_name
[ ]
get the value fromPLACES
associated withold_name
and assign it toold_place
Code
87 # look up where the user is at now
88 old_name = PLAYER["place"]
89 old_place = PLACES[old_name]
C. Modify do_go()
: look up what is in that direction from here#
In this section we’ll use the direction (ie. "east"
) the player wants to go
to look up the name of the next place (if any) in the current place dictionary
as seen here.
[ ]
use the.get()
method onold_place
to get the value associated with thedirection
key and assign it tonew_name
[ ]
Check ifnew_name
is falsy. If so:[ ]
Use theerror()
function to print a message saying:"Sorry, you can't go direction from here.")
[ ]
return
Code
91 # look up what is in that direction from here
92 new_name = old_place.get(direction)
93
94 # print an error if there is nothing in that direction
95 if not new_name:
96 error(f"Sorry, you can't go {direction} from here.")
97 return
D. Modify do_go()
: figure out where we’re going#
Next we’ll get the info for where the player is going from PLACES
, or print an
error message if it’s not found.
[ ]
use the.get()
method onPLACES
to get the value associated with thenew_name
key and assign it tonew_place
[ ]
Check ifnew_place
is falsy. If so:[ ]
Use theerror()
function to print a message saying:"Woops! The information about new_name seems to be missing."
This will only happen if you made a mistake somewhere in your code. But just in case we do, we want to have a clear error message so we can tell what went wrong.
[ ]
return
Code
99 # look up the place information
100 new_place = PLACES.get(new_name)
101
102 # this should never happen if we write the code correctly
103 # but just in case there is no key in PLACES matching
104 # the new name, print an error
105 if not new_place:
106 error(f"Woops! The information about {new_name} seems to be missing.")
107 return
E. Modify do_go()
: update the players place and describe it#
Finally, we can now update the PLAYER
dictionary to point to the new place
name and print the place information.
[ ]
In thePLAYER
dictionary change value associated with the"place"
key tonew_name
[ ]
Print the values associated with the"name"
and"description"
keys of thenew_place
dictionary
Code
109 # move the player to the new place
110 PLAYER["place"] = new_name
111
112 # print information about the new place
113 print(f"\n{new_place['name']}\n")
114 print(new_place["description"], "\n")