1

I'm making a simple ball game using a 2D map. The amount of balls on the map is variable. When starting the game I load the map and look for balls (The balls are unique letters). I append these ball names to a list. I also have a Ball class. __init__ contains the coordinates of the ball and the class contains a couple of methods.

Here comes the problem: I want to create objects of each ball using the Ball class, with the object name corresponding to the letter belonging to the ball.

I tried this:
(The map is a txt file looking like this:)
0 0 0 0
0 0 X 0
0 A 0 B
Where the zero's represent empty tiles.

class Ball:
    def __init__( self, x, y):
        self.x = x
        self.y = y

map_data = np.genfromtxt('map.txt', dtype=str)
ball_names = []

for row in variables.map_data:
    for i in row:
        if i.isalpha():
           ball_names.append(i)   
for ball in ball_names:
    coordinates = np.where(map_data == ball)
    ball = Ball(coordinates[0], coordinates[1])
    

But then I want the object to be named after the string contained by the variable ball, not 'ball'. I know this can be done using exec(), but I've been told to avoid that function.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
Joris
  • 13
  • 2

1 Answers1

1

Generating variables dynamically with exec is a bad idea. As in fact variables will be totally hidden from developer. Supporting such code will be a nightmare and it's going to be a giant source of problems.

Instead, why don't you create a dict of balls?

my_balls = dict()
for ball in ball_names:
    coordinates = np.where(map_data == ball)
    my_balls[ball] = Ball(coordinates[0], coordinates[1])

But if you really want to create a variable, then:

exec(f'{ball} = Ball({coordinates[0]}, {coordinates[1]})')
go2nirvana
  • 1,598
  • 11
  • 20
  • I've thought about using a dictionary instead before, but I wouldn't know how to perform operations on the coordinates of the balls. When using classes I have a method in Ball which can alter these. To move ball X to the right I'd call X.move_right(amount of steps). How could I do this using the dictionary? – Joris Dec 31 '20 at 12:39
  • Just access needed ball and call whatever methods you want. `my_balls['some_ball_name'].some_ball_method()` – go2nirvana Dec 31 '20 at 12:42