0

I am trying to fix a very simple pygame minigame but I'm not very familiar with dictionaries. So I have a dictionary with four monsters (keys) and their respective starting positions as values in a list. For drawing them with pygame or make them move I wanted to use a for-loop to iterate through the dictionary, but it seems like I can't index the value of a dictionary, so I'm a bit stuck.

Below is what I was trying for drawing the monsters:

monsterStart={"M1":[40,40], "M2":[580,40], "M3":[40,380], "M4":[580,380]}
global monsterStart

def drawMonsters(monsters): 
    monsters=monsterStart

    for monster in monsters: 
        monsterPosition = monsters[monster]
        MP_x = monsterPosition[0]
        MP_y = monsterPosition[1]
        pygame.draw.rect(DISPLAYSURFACE, Blue, (MP_x, MP_y, 20, 20)) 

drawMonsters(monsterStart)

When I try to run my code it gives me this error:

Traceback (most recent call last):
File "cave_room_bonus.py", line 457, in drawMonsters
    monsterPosition = monsters[monster]
TypeError: tuple indices must be integers or slices, not dict

And unfortunately, I can't figure out what's wrong or think of another way to program this. I'm rather new in the world of programming, so I would appreciate some help!

SuperKogito
  • 2,998
  • 3
  • 16
  • 37
  • Possible duplicate of [Iterating over dictionaries using 'for' loops](https://stackoverflow.com/questions/3294889/iterating-over-dictionaries-using-for-loops) – Thierry Lathuille May 05 '19 at 12:02
  • `monsters` is somehow a tuple and `monster` is a dictionary. `monsterStart` is likely a tuple of dictionaries. I'm sure this is not the only code you have. – Austin May 05 '19 at 12:02
  • Also, remove `monsters=monsterStart` from the beginning of your function. – Thierry Lathuille May 05 '19 at 12:03

1 Answers1

1

You can get a list of monsters (which I assume are M1, M2, ... , Mn) by accessing keys in your dictionary. Since keys should be unique, those could act like what you're describing.

Your function could then look like this:

# Passing our dictionary as a default argument for illustrative purposes.
def drawMonsters(monster_start_dict=monsterStart):    
    for monster in monster_start_dict.keys(): 
        monsterPosition = monster_start_dict[monster]
        MP_x = monsterPosition[0]
        MP_y = monsterPosition[1]
        pygame.draw.rect(DISPLAYSURFACE, Blue, (MP_x, MP_y, 20, 20))

You can also run this to see how the dictionary works:

for monster in monsterStart.keys():
    monsterPosition = monsterStart[monster]
    print(monster, ' -> ', monsterPosition)

Output:

M1  ->  [40, 40]
M2  ->  [580, 40]
M3  ->  [40, 380]
M4  ->  [580, 380]

Or, directly call the value positions (0 and 1, as you have in your function):

for monster in monsterStart.keys(): 
    print('X -> ', monsterStart[monster][0])
    print('y -> ', monsterStart[monster][1])
    print('')

Output:

X ->  40
y ->  40

X ->  580
y ->  40

X ->  40
y ->  380

X ->  580
y ->  380

This will allow you to thin-out your function even more:

def drawMonsters(monster_start_dict=monsterStart):    
    for m in monster_start_dict.keys(): 
        pygame.draw.rect(DISPLAYSURFACE, Blue, (monster_start_dict[m][0], monster_start_dict[m][1], 20, 20))

Finally, using list comprehension:

def drawMonsters(monster_start_dict=monsterStart):
    [pygame.draw.rect(DISPLAYSURFACE, Blue, (monster_start_dict[m][0], monster_start_dict[m][1], 20, 20)) for m in monster_start_dict.keys()]
Mark Moretto
  • 2,344
  • 2
  • 15
  • 21