I am working on a text based game for class. I have written a majority of it but when I go to test it I am getting a TypeError: unhasable type: 'list' error.
def show_instructions():
# Defines what the instructions so they are easily recalled later
print('x' * 75)
print('Escape from the Magic Prison!')
print('Collect six talismans from the different rooms in the prison.')
print('Avoid the Warden at all cost!')
print('If there is an item in the room you are in say: "Get [Item Name]"')
print('Move to different rooms by saying: "Go [Direction]"')
print('x' * 75)
# Print x * 75 to break up the lines so it looks better
def player_status(inventory, current_room, rooms):
# Defines player_status to easily recall this below
print('x' * 75)
print('You are currently in', current_room)
print('Current Inventory:', inventory)
if 'item' in rooms[current_room]:
print('There is a', rooms[current_room]['item'], 'on the floor.')
print('x' * 75)
def game():
inventory = []
# Sets user to start with no inventory
rooms = {
'Jail Cell': {'South': 'Shower Room'},
'Shower Room': {'North': 'Jail Cell', 'East': 'Mess Hall', 'item': 'Razor Talisman'},
'Mess Hall': {'West': 'Shower Room', 'North': 'Kitchen', 'East': 'Commissary', 'South': 'Yard',
'item': 'Spoon Talisman'},
'Yard': {'North': 'Mess Hall', 'item': 'Wire Cutter Talisman'},
'Kitchen': {'South': 'Mess Hall', 'item': 'Ladle Talisman'},
'Commissary': {'West': 'Mess Hall', 'North': "Warden's Office", 'East': 'Library', 'item': 'Token Talisman'},
"Warden's Office": {'South': 'Commissary', 'item': 'Warden'},
'Library': {'West': 'Commissary', 'item': 'Date Stamp Talisman'}
}
# Defines the rooms, which directions you can go from while in that room, and what item the room amy have.
current_room = ['Jail Cell']
# Sets the users starting room.
show_instructions()
while True:
player_status(inventory, current_room, rooms)
command = input('What would you like to do? \n')
if len(inventory) == 6:
print('You got all of the required talisman!')
print('You are now able to walk through walls after obtaining all of the talismans!')
print('You leave the prison using your new ability.')
print('x' * 75)
print('Game over, you won!')
print('x' * 75)
elif command.split()[0].capitalize() == 'GO':
command = command.split()[1].capitalize()
if command in rooms[current_room]:
current_room = rooms[current_room][command]
if current_room == "Warden's Office":
print("You have entered the Warden's Office! \n The warden binds you with their magic."
"\n The warden locks you back into your jail cell.")
print('x' * 75)
print('Game Over \n Thanks for playing.')
print('x' * 75)
break
else:
print('There is no door that way.')
elif command.split()[0].capitalize() == 'GET':
command = command.split()[1].capitalize()
if command in rooms[current_room]['item']:
inventory.append(command)
del rooms[current_room]['item']
else:
print('Invalid input, check spelling.')
else:
print('Invalid input, check spelling.')
game()
This is the code I am running and here is the exact error I am getting:
Traceback (most recent call last):
File "C:\Users\tyler\PycharmProjects\VariousSchool\TextBasedGame.py", line 84, in <module>
game()
File "C:\Users\tyler\PycharmProjects\VariousSchool\TextBasedGame.py", line 50, in game
player_status(inventory, current_room, rooms)
File "C:\Users\tyler\PycharmProjects\VariousSchool\TextBasedGame.py", line 22, in player_status
if 'item' in rooms[current_room]:
~~~~~^^^^^^^^^^^^^^
TypeError: unhashable type: 'list'
I am not sure what else to try, I reviewed the variables and everything that I had but it keeps coming back to this error.
CodePudding user response:
A mutable type in Python is not hashable, because the behaviour of equality might change as the elements are mutated, which should change the hash (which is not possible). Since sets and dictionaries rely on hashing keys, unhashable elements cannot be keys of dictionaries, and elements of sets.
A good alternative to lists that are hashable are immutable lists, also called tuples. Try rooms[tuple(current_room)]
.
Although this should work, your code is suspicious, since current_room seems to be a singleton. Maybe you meant current_room = 'jail Cell'
?
CodePudding user response:
From what I can tell, in line 22, you are trying to get the available commands for the current room, where the current room is stored in a variable named current_room
. However, current_room
is a list, and the part in the brackets needs to be a hashable. I think you should change the rooms[current_room]
to rooms[current_room[0]]
to get the actual current room in the list. Although converting to other iterables such as tuples make them hashable, using them will probably result in a KeyError as the keys of the rooms
dictionary are strings.