I've been working on a text-based adventure game and currently I'm working on splitting up one large game script I have into separate modules.
This is the main game module containing the game's logic. Within the main()
function I have defined instances of classes
from gameworld import *
def main():
player = Player("Jeff", 100)
bag = Bag([])
location = Location('introd')
command = ' '
while command != "":
command = input('>>> ')
if command in location.room.exits:
location.travel(command)
elif command == 'look':
location.room_desc()
elif command == '':
print('You have to say what it is you want to do!')
command = '#'
elif command == 'search':
location.search_room()
elif command.split()[0] == 'Take':
bag.check_take(command.split()[1])
elif command == 'Inventory':
bag.check_inv()
else:
print('Invalid command')
if __name__ == '__main__':
main()
Below is an excerpt from the gameworld module. It includes the functions that I'm having difficulty with. The Location.key_check
and Bag.check_take
functions.
#gameworld.py
class Room:
def __init__(self, name, description, exits, actions, roominv, roomkey, lock):
self.name = name
self.description = description
self.exits = exits
self.actions = actions
self.roominv = roominv
self.roomkey = roomkey
self.lock = lock
class Location:
def __init__(self, room):
self.room = world[room]
def key_check(self, new_room_name):
if world[new_room_name].lock and world[new_room_name].roomkey not in bag.inventory:
self.no_key()
else:
world[new_room_name].lock = False
self.set_room(new_room_name)
self.room_desc()
class Bag():
def __init__(self, inventory):
self.inventory = inventory
def add_to_inv(self, key):
self.inventory.append(location.room.roominv[key])
del location.room.roominv[key]
def none_here(self, key):
print("You can't find a", key)
def check_take(self, key):
if location.room.roominv and key in location.room.roominv:
self.add_to_inv(key)
print('you take the', key)
else:
self.none_here(key)
When I run the game, and attempt to pick up an item, I receive this traceback error:
Traceback (most recent call last):
File "C:\Users\Daniel\Python 3.6\Scripts\PythonPR\PythonPR\FlubbosModuleTest.py", line 31, in <module>
main()
File "C:\Users\Daniel\Python 3.6\Scripts\PythonPR\PythonPR\FlubbosModuleTest.py", line 23, in main
bag.check_take(command.split()[1])
File "C:\Users\Daniel\Python 3.6\Scripts\PythonPR\PythonPR\gameworld.py", line 81, in check_take
if location.room.roominv and key in location.room.roominv:
NameError: name 'location' is not defined
I receive a similar error when attempting to move to a locked room and the key_check
method runs. When the code is all contained in the same script, it runs fine with no problem accessing these class instances.
You need to pass the location variable when you are calling bag.check_take as an argument as location is not defined and is not in scope inside the Bag class. You need to pass the variable represent other object when you call a class member function.
In the case that you've designed your Bag
to have an inventory attribute which you update.
def add_to_inv(self, key):
self.inventory.append(location.room.roominv[key])
del location.room.roominv[key]
Nitpick : move the mutation of the room inventory for a location to a manager function. See rest of answer below to get an idea.
You can make check_take
into a function that take a key, bag and location. This function can be imported and passed key, bag and location accordingly.
def check_take(key, bag, location=None):
if location.room.roominv and key in location.room.roominv:
bag.add_to_inv(key)
else:
bag.none_here(key)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.