Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community!
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

Jenna Dalgety
7,791 Pointsdungeon.py 'function' object is not subscriptable
So, I'm working on my dungeon game, specifically trying to get the monster to only move one space instead of randomly anywhere in the dungeon. I get the above-mentioned error called on line 52. Not sure why or what I can do to troubleshoot it. Also, I'm pretty sure my code is fairly un-DRY. Any guidance/feedback is appreciated!
# make monster move
# leave breadcrumbs for rooms you've visited
import os
import random
size = 8 # test size
DUNGEON = []
for x in range(size):
for y in range(size):
DUNGEON.append((x,y))
def clear():
os.system('cls' if os.name == 'nt' else 'clear')
def get_locations():
monster = random.choice(DUNGEON)
door = random.choice(DUNGEON)
player = random.choice(DUNGEON)
if monster == door or monster == player or door == player:
return get_locations()
else:
return monster, door, player
def move_player(player, move):
x, y = player
if move == 'LEFT':
y -= 1
elif move == 'RIGHT':
y += 1
elif move == 'UP':
x -= 1
elif move == 'DOWN':
x += 1
return x, y
def avail_monster_moves(monster):
monster_moves = ['LEFT', 'RIGHT', 'UP', 'DOWN']
if monster == door:
return avail_monster_moves(monster)
if monster[1] == 0:
monster_moves.remove('LEFT')
if monster[0] == 0:
monster_moves.remove('UP')
if monster[1] == size - 1:
monster_moves.remove('RIGHT')
if monster[0] == size - 1:
monster_moves.remove('DOWN')
return monster_moves
def move_monster(monster, monster_moves):
m_move = random.choice(monster_moves)
x, y = monster
if m_move == 'LEFT':
y -= 1
if m_move == 'RIGHT':
y += 1
if m_move == 'UP':
x -= 1
if m_move == 'DOWN':
x += 1
return x, y
# monster = random.choice(DUNGEON)
# if monster == door:
# return move_monster()
# else:
# return monster
def get_moves(player):
moves = ['LEFT', 'RIGHT', 'UP', 'DOWN', 'QUIT']
if player[1] == 0:
moves.remove('LEFT')
if player[0] == 0:
moves.remove('UP')
if player[1] == size - 1:
moves.remove('RIGHT')
if player[0] == size - 1:
moves.remove('DOWN')
return moves
def draw_map(player):
dungeon_lid = ' _' * size
print(dungeon_lid)
tile = '|{}'
dungeon_array = []
for i in range(len(DUNGEON)):
if (i + 1) % (size) == 0:
dungeon_array.append(i)
for idx, cell in enumerate(DUNGEON):
if idx not in dungeon_array:
if cell == player:
print(tile.format('X'), end='')
elif cell == monster:
print(tile.format('O'), end='')
elif cell == door:
print(tile.format('!'), end='')
else:
print(tile.format('_'), end='')
else:
if cell == player:
print(tile.format('X|'))
elif cell == monster:
print(tile.format('O|'))
elif cell == door:
print(tile.format('!|'))
else:
print(tile.format('_|'))
monster, door, player = get_locations()
print('Welcome to the dungeon!')
while True:
moves = get_moves(player)
print('You are currently in room {}'.format(player))
draw_map(player)
print('You can move {}'.format(moves))
# print('Enter QUIT to quit')
move = input('> ')
clear()
move = move.upper()
if move not in moves:
print('Please enter a valid direction')
else:
if move == 'QUIT':
break
if move in moves:
player = move_player(player, move)
monster = avail_monster_moves(move_monster)
else:
print('** walls are hard...stop walking into them **')
continue
if player == door:
print("Congratulations, adventuror! You've escaped the dungeon!")
break
elif player == monster:
print("You've been ripped limb from limb by the monster. Sorry about your life.")
break
2 Answers

fahad lashari
6,771 PointsHi Jenna. I would love you help you in more detail however for now have a look at my code. I tried to do something similar. My aim was to basically make the monster chase the player around by spawning around him every time the player moved and I added an additional invisible monster which also stayed just 1 block outside from the players location. The twist was the if the player moved in a different direction to avoid the monster they could see on the map. They would get sometimes get eaten by the hidden monster.
And then there are additional mines. Each monster also does a different amount of damage etc. Monster are selected at random.
I hope you have as much fun programming this as I did. I wanted to add A LOT more stuff that I listed out in the objectives section however due to the lack of time I could not finish. The code could definitely benefit from DRY programming as it was coded at the time I was learning. The game however works perfectly.
May be you can finish it off =)
Before I post the snapshot some improvements to your code:
The error in your code is on line 163
monster = avail_monster_moves(move_monster)
In line 46 you are passing the monster locations to the function as such:
def avail_monster_moves(monster):
However on line 163 you are not sending the correct information to that function. Therefore in like 163 the function is not being called correctly Change this to:
monster = avail_monster_moves(monster)
This solves the error you mentioned.
I would also suggest using 4 spaces for the indents to make it easier for other people to read the code.
Here is a snapshot of my workspaces:
Run the dungeon_game.py file
Good luck with the rest of your studies. If you anymore questions feel free to ask.
Kind regards,

Jenna Dalgety
7,791 PointsThanks much for all the input! Definitely solved my problem. And your Dungeon looks quite rad!