Stage 6 - Use Items¶
Introduction¶
Our game is progressing nicely. They player can move between multiple rooms, interact with different types of characters. We also have different items in these room.
The next step is to allow the player to collect the items and use them.
To achieve this we will:
create a backpack variable that can store items
add a take command that collects the items
add a backpack command to list the items in the backpack
restrict the fight weapon to items in the backpack
Class Diagram¶
If we look at the class diagram, we notice that there are no changes. All of the changes in this section will be made in the main.py file, and will not involve adjusting any classes.
Creating a backpack¶
The first thing we need to create is a backpack variable, so we can store the items we collect. To achieve this, we need a variable type that can hold multiple values. In Python these are called collections. We will be using lists, a type of collection that you will be familiar with.
Collections in Python
In Python, a collection is a way to group things together. There are different types of collections like lists, sets, and dictionaries. You can use them to store a bunch of values or items, like a shopping list or a list of names. Each type of collection has different rules and ways to use it. By choosing the right type of collection for what you need, it can help you write better code that works faster and is easier to read.
Python has following collections built it:
Lists: ordered collections of values, which can be of any data type. They are created using square brackets [] and values are separated by commas.
Tuples: similar to lists, but they are immutable, which means that their values cannot be changed after they are created. They are created using parentheses () and values are separated by commas.
Sets: unordered collections of unique values. They are created using curly braces {} or the set() constructor.
Dictionaries: unordered collections of key-value pairs. They are created using curly braces {} and key-value pairs are separated by commas, with a colon : between the key and value.
It also has modules to support other collections:
Arrays: used to store a sequence of values of the same data type. They are created using the array module.
Queues: data structures that use a first-in, first-out (FIFO) method to store and retrieve data. They are implemented using the queue module.
Stacks: Stacks are data structures that use a last-in, first-out (LIFO) method to store and retrieve data. They are implemented using the stack module.
Lists are the perfect collection for our purposed. It can start as empty and we can then use the append()
method to add items as they are picked up by the user. We can also check if out backpack contains an item using the in
operator. We can access the time using list indexation, as well as using pop
to remove the item from the backpack. So let’s create it.
Open main.py and add the highlighted code below:
1# main.py
2
3from room import Room
4from character import Enemy, Friend
5from item import Item
6
7# create rooms
8cavern = Room("Cavern")
9cavern.description = ("A room so big that the light of your torch doesn’t reach the walls.")
10
11armoury = Room("Armoury")
12armoury.description = ("The walls are lined with racks that once held weapons and armour.")
13
14lab = Room("Laboratory")
15lab.description = ("A strange odour hangs in a room filled with unknownable contraptions.")
16
17# link rooms
18cavern.link_rooms(armoury,"south")
19armoury.link_rooms(cavern,"north")
20armoury.link_rooms(lab,"east")
21lab.link_rooms(armoury,"west")
22
23# create characters
24ugine = Enemy("Ugine")
25ugine.description = "a huge troll with rotting teeth."
26ugine.weakness = "cheese"
27
28nigel = Friend("Nigel")
29nigel.description = "a burly dwarf with golden bead in woven through his beard."
30nigel.conversation = "Well youngan, what are you doing here?"
31
32# add characters to rooms
33armoury.character = ugine
34lab.character = nigel
35
36# create items
37cheese = Item("Cheese")
38cheese.description = "super smelly"
39
40chair = Item("Chair")
41chair.description = "designed to be sat on"
42
43elmo = Item("Elmo")
44elmo.description = "wanting to be tickled"
45
46# add items to rooms
47cavern.item = chair
48armoury.item = elmo
49lab.item = cheese
50
51'''
52# describe the rooms
53cavern.describe()
54armoury.describe()
55lab.describe()
56'''
57
58# initialise variables
59running = True
60current_room = cavern
61backpack = []
62
63# ----- MAIN LOOP -----
64while running:
65 current_room.describe()
66
67 command = input("> ").lower()
68
69 if command in ["north", "south", "east", "west"]:
70 current_room = current_room.move(command)
71 elif command == "talk":
72 if current_room.character is not None:
73 current_room.character.talk()
74 else:
75 print("There is no one here to talk to")
76 elif command == "hug":
77 if current_room.character is not None:
78 current_room.character.hug()
79 else:
80 print("There is no one here to hug")
81 elif command == "fight":
82 if current_room.character is not None:
83 weapon = input("What will you fight with? > ").lower()
84 if current_room.character.fight(weapon):
85 current_room.character = None
86 else:
87 running = False
88 else:
89 print("There is no one here to fight")
90 elif command == "quit":
91 running = False
92 else:
93 print("I don't understand.")
We don’t need to investigate this line of code, as we all know what it does.
Add take command¶
Now that we have a backpack we need to create a command that allows the user to pick up items in the room and place them in the backpack. We will use take as that command.
Still working in main.py add the take command using the highlighted code below:
1# main.py
2
3from room import Room
4from character import Enemy, Friend
5from item import Item
6
7# create rooms
8cavern = Room("Cavern")
9cavern.description = ("A room so big that the light of your torch doesn’t reach the walls.")
10
11armoury = Room("Armoury")
12armoury.description = ("The walls are lined with racks that once held weapons and armour.")
13
14lab = Room("Laboratory")
15lab.description = ("A strange odour hangs in a room filled with unknownable contraptions.")
16
17# link rooms
18cavern.link_rooms(armoury,"south")
19armoury.link_rooms(cavern,"north")
20armoury.link_rooms(lab,"east")
21lab.link_rooms(armoury,"west")
22
23# create characters
24ugine = Enemy("Ugine")
25ugine.description = "a huge troll with rotting teeth."
26ugine.weakness = "cheese"
27
28nigel = Friend("Nigel")
29nigel.description = "a burly dwarf with golden bead in woven through his beard."
30nigel.conversation = "Well youngan, what are you doing here?"
31
32# add characters to rooms
33armoury.character = ugine
34lab.character = nigel
35
36# create items
37cheese = Item("Cheese")
38cheese.description = "super smelly"
39
40chair = Item("Chair")
41chair.description = "designed to be sat on"
42
43elmo = Item("Elmo")
44elmo.description = "wanting to be tickled"
45
46# add items to rooms
47cavern.item = chair
48armoury.item = elmo
49lab.item = cheese
50
51'''
52# describe the rooms
53cavern.describe()
54armoury.describe()
55lab.describe()
56'''
57
58# initialise variables
59running = True
60current_room = cavern
61backpack = []
62
63# ----- MAIN LOOP -----
64while running:
65 current_room.describe()
66
67 command = input("> ").lower()
68
69 if command in ["north", "south", "east", "west"]:
70 current_room = current_room.move(command)
71 elif command == "talk":
72 if current_room.character is not None:
73 current_room.character.talk()
74 else:
75 print("There is no one here to talk to")
76 elif command == "hug":
77 if current_room.character is not None:
78 current_room.character.hug()
79 else:
80 print("There is no one here to hug")
81 elif command == "fight":
82 if current_room.character is not None:
83 weapon = input("What will you fight with? > ").lower()
84 if current_room.character.fight(weapon):
85 current_room.character = None
86 else:
87 running = False
88 else:
89 print("There is no one here to fight")
90 elif command == "take":
91 if current_room.item is not None:
92 backpack.append(current_room.item)
93 print(f"You put {current_room.item.name} into your backpack")
94 current_room.item = None
95 else:
96 print("There is nothing here to take")
97 elif command == "quit":
98 running = False
99 else:
100 print("I don't understand.")
Save main.py predict what you think will happen and then run the code. What happens to the room description after you take an item?
In investigating this code, most of it should be familiar from our previous command event handlers. The different code is:
backpack.append(current_room.item)
→ take theItem
object in the room and adds it to the end of thebackpack
list.print(f"You put {current_room.item.name} into your backpack")
→ informs the user that they have collected the itemcurrent_room.item = None
→ removes theItem
object from the room by setting theRoom
object’sitem
attribute toNone
Add backpack command¶
Now that we are putting items in the backpack, we need to create a way for the user to see what they have. We will make a new backpack command that lists the Item
objects stored in their backpack.
Still working in main.py, add the code below:
1# main.py
2
3from room import Room
4from character import Enemy, Friend
5from item import Item
6
7# create rooms
8cavern = Room("Cavern")
9cavern.description = ("A room so big that the light of your torch doesn’t reach the walls.")
10
11armoury = Room("Armoury")
12armoury.description = ("The walls are lined with racks that once held weapons and armour.")
13
14lab = Room("Laboratory")
15lab.description = ("A strange odour hangs in a room filled with unknownable contraptions.")
16
17# link rooms
18cavern.link_rooms(armoury,"south")
19armoury.link_rooms(cavern,"north")
20armoury.link_rooms(lab,"east")
21lab.link_rooms(armoury,"west")
22
23# create characters
24ugine = Enemy("Ugine")
25ugine.description = "a huge troll with rotting teeth."
26ugine.weakness = "cheese"
27
28nigel = Friend("Nigel")
29nigel.description = "a burly dwarf with golden bead in woven through his beard."
30nigel.conversation = "Well youngan, what are you doing here?"
31
32# add characters to rooms
33armoury.character = ugine
34lab.character = nigel
35
36# create items
37cheese = Item("Cheese")
38cheese.description = "super smelly"
39
40chair = Item("Chair")
41chair.description = "designed to be sat on"
42
43elmo = Item("Elmo")
44elmo.description = "wanting to be tickled"
45
46# add items to rooms
47cavern.item = chair
48armoury.item = elmo
49lab.item = cheese
50
51'''
52# describe the rooms
53cavern.describe()
54armoury.describe()
55lab.describe()
56'''
57
58# initialise variables
59running = True
60current_room = cavern
61backpack = []
62
63# ----- MAIN LOOP -----
64while running:
65 current_room.describe()
66
67 command = input("> ").lower()
68
69 if command in ["north", "south", "east", "west"]:
70 current_room = current_room.move(command)
71 elif command == "talk":
72 if current_room.character is not None:
73 current_room.character.talk()
74 else:
75 print("There is no one here to talk to")
76 elif command == "hug":
77 if current_room.character is not None:
78 current_room.character.hug()
79 else:
80 print("There is no one here to hug")
81 elif command == "fight":
82 if current_room.character is not None:
83 weapon = input("What will you fight with? > ").lower()
84 if current_room.character.fight(weapon):
85 current_room.character = None
86 else:
87 running = False
88 else:
89 print("There is no one here to fight")
90 elif command == "take":
91 if current_room.item is not None:
92 backpack.append(current_room.item)
93 print(f"You put {current_room.item.name} into your backpack")
94 current_room.item = None
95 else:
96 print("There is nothing here to take")
97 elif command == "backpack":
98 if backpack == []:
99 print("It is empty")
100 else:
101 print("You have:")
102 for item in backpack:
103 print(f"- {item.name.capitalize()}")
104 elif command == "quit":
105 running = False
106 else:
107 print("I don't understand.")
Save the main.py file, predict and then run your code. This time we should do some serious testing.
We need to make sure that:
we can pick up all the items in all the rooms
the items are added to the backpack when they are picked up
the items are removed from the room when they are picked up
If your testing all works out, then it’s time to investigate the code.
elif command == "backpack":
→ the event handler for thebackpack
commandif backpack == []:
→ checks if the backpack is emptyprint("It is empty")
→ informs the user that the backpack is emptyelse:
→ if the backpack is not emptyprint("You have:")
→ displays a message before listing backpack itemsfor item in backpack:
→ iterates over each item in the backpackprint(f"- {item.name.capitalize()}")
→ capitalizes and prints the name of the currentitem
that thefor
loop is dealing with.
Adjusting the fight command¶
Finally we will adjust the fight
event handler so the user can only use items they currently have in their backpack.
Still working in main.py, add the code below.
1# main.py
2
3from room import Room
4from character import Enemy, Friend
5from item import Item
6
7# create rooms
8cavern = Room("Cavern")
9cavern.description = ("A room so big that the light of your torch doesn’t reach the walls.")
10
11armoury = Room("Armoury")
12armoury.description = ("The walls are lined with racks that once held weapons and armour.")
13
14lab = Room("Laboratory")
15lab.description = ("A strange odour hangs in a room filled with unknownable contraptions.")
16
17# link rooms
18cavern.link_rooms(armoury,"south")
19armoury.link_rooms(cavern,"north")
20armoury.link_rooms(lab,"east")
21lab.link_rooms(armoury,"west")
22
23# create characters
24ugine = Enemy("Ugine")
25ugine.description = "a huge troll with rotting teeth."
26ugine.weakness = "cheese"
27
28nigel = Friend("Nigel")
29nigel.description = "a burly dwarf with golden bead in woven through his beard."
30nigel.conversation = "Well youngan, what are you doing here?"
31
32# add characters to rooms
33armoury.character = ugine
34lab.character = nigel
35
36# create items
37cheese = Item("Cheese")
38cheese.description = "super smelly"
39
40chair = Item("Chair")
41chair.description = "designed to be sat on"
42
43elmo = Item("Elmo")
44elmo.description = "wanting to be tickled"
45
46# add items to rooms
47cavern.item = chair
48armoury.item = elmo
49lab.item = cheese
50
51'''
52# describe the rooms
53cavern.describe()
54armoury.describe()
55lab.describe()
56'''
57
58# initialise variables
59running = True
60current_room = cavern
61backpack = []
62
63# ----- MAIN LOOP -----
64while running:
65 current_room.describe()
66
67 command = input("> ").lower()
68
69 if command in ["north", "south", "east", "west"]:
70 current_room = current_room.move(command)
71 elif command == "talk":
72 if current_room.character is not None:
73 current_room.character.talk()
74 else:
75 print("There is no one here to talk to")
76 elif command == "hug":
77 if current_room.character is not None:
78 current_room.character.hug()
79 else:
80 print("There is no one here to hug")
81 elif command== "fight":
82 if current_room.character is not None:
83 weapon = input("What will you fight with? > ").lower()
84 available_weapons = []
85 for item in backpack:
86 available_weapons.append(item.name)
87 if weapon in available_weapons:
88 if current_room.character.fight(weapon):
89 current_room.character = None
90 else:
91 running = False
92 else:
93 print(f"You don't have {weapon}")
94 print(f"{current_room.character.name} strikes you down.")
95 running = False
96 else:
97 print("There is no one here to fight")
98 elif command == "take":
99 if current_room.item is not None:
100 backpack.append(current_room.item)
101 print(f"You put {current_room.item.name} into your backpack")
102 current_room.item = None
103 else:
104 print("There is nothing here to take")
105 elif command == "backpack":
106 if backpack == []:
107 print("It is empty")
108 else:
109 print("You have:")
110 for item in backpack:
111 print(f"- {item.name.capitalize()}")
112 elif command == "quit":
113 running = False
114 else:
115 print("I don't understand.")
Save main.py. Predict what you think will happen, and then run the code.
Let’s investigate that code, but be aware that there are a number of different sections to that code.
First we need to check that the user actually has the entered weapon in their backpack.
available_weapons = []
→ creates a new list that contains thename
attribute for all items in the backpack.the backpack stored
Item
objectsthe user entered the item name as a string
therefore, we need to create a list of the name of all the items in the backpack
for item in backpack:
→ iterates over each item in the backpackavailable_weapons.append(item.name)
→ add thename
attribute of the current item to theavailable_weapons
list.if weapon in available_weapons:
→ checks that the weapon entered by the user is in the list of available weapons.
If the user entered an available weapon, then we need to fight with this weapon. Lines 88
to 91
are the same as before, but the have been indented one level. To to this easily increase a block of code’s indentation:
highlight lines
88
to91
, ether using the mouse or shift + arrow keys.then press the Tab key once
If the user didn’t enter an available weapon, then we need to inform them, then make them loose the fight and end the game. This happens in lines 92
to 95
else:
→ the weapon entered is not in theavailable_weapons
listprint(f"You don't have {weapon}")
→ inform the user that they do not have that item in the backpackprint(f"{current_room.character.name} strikes you down.")
→ resolves the fight as a defeat for the userrunning = False
ends the game by exiting the main loop.
Testing¶
We now need to test our code. This code now has nested branches of if statements so we have to be aware of testing all the possible options. We will test with Ugine as we know his weakness is cheese.
Collected Cheese |
Fought Ugine |
Weapon Used |
Expected Result |
Actual Result |
---|---|---|---|---|
Yes |
Yes |
Cheese |
You strike Ugine down with cheese. |
|
Yes |
Yes |
Elmo |
Ugine crushes you. Puny adventurer |
|
No |
Yes |
Cheese |
You don’t have cheese… |
If your code passes all the tests, it’s time to make some code in the stage 6 task.
Stage 6 task¶
You need to apply the changes we made to your other characters. Especially if you have another enemy. Make sure that the user can collect their weakness and use it against them.