1

My very first post, sorry if I made any mistakes!

I'm messing around the pygame library, and I'm extremely new to python in general. I have created 3 enemies classes and they work as intended, however, this is how I make them move (I call the move function stored inside the class).

I wonder if there is a more clean way to do things. I have many other enemies to code and this seems very repetitive to type, so it's a sign I'm doing something wrong.

I tried creating a "control list" where I list every enemy list there is and I try to access them through their index but it isn't working. I also tried to concatenate but I'm getting an error saying I can't concatenate list names, another error was that my list names turned into strings (yes, I tried using quotation marks). I'm sure this will be a simple fix, but I spent 3 days and I wrap my head around it. If it's possible to do so

The sample of my code so far - it is located in the main run loop of my game.

    for giant in lst_enemy_giants:
        giant.move()
    else:
        pass

    for spider in lst_enemy_spiders:
        spider.move()
    else:
        pass

    for goblin in lst_enemy_goblin:
        giant.move()
    else:
        pass

# The pattern the I want
    for ENEMY in lst_enemy_ENEMY:
        ENEMY.move()

# where ENEMY is any enemy list that can be stored somewhere

1 Answer 1

3

Just chain the iterators together.

from itertools import chain

for enemy in chain(lst_enemy_giants, lst_enemy_spiders, lst_enemy_goblin):
    enemy.move()

This is a slightly nicer way of writing a nested loop like

for enemy_list in [lst_enemy_giants, lst_enemy_spiders, lst_enemy_goblin]:
    for enemy in enemy_list:
        enemy.move()

Unrelated, but I recommend keeping a single dict like

enemies = {'giants': [...], 'spiders': [...], 'goblins': [...]}

rather than three separate variables referencing separate lists. You can still use, for example, enemies['giants'] anywhere you would have used lst_enemy_giants, but now you can write

for enemy in chain(*enemies.values()):
    enemy.move()
Sign up to request clarification or add additional context in comments.

5 Comments

Interesting. Of course, all of the enemy objects need a move() method, which is an Interface principle. I wonder if Type Hints can help enforce this in modern Python3.
Yes, using typing.Protocol. That's beyond the scope of this question, which is addressing a situation where it is already assumed that each enemy object has a move method.
Oh the second method worked wonderfully! I made so much sense too. I didn't know that I could actually do that. Thank you so much!
@chepner would you mind providing an example with typing.Protocol? I am very interested in how you might make this technique type-safe.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.