简体   繁体   中英

Python: Creating many instances of a class

I have a class called Unit which is a generic unit in a game. An instance of this Unit can be Cavalry , Infantry etc. and each unit has coordinates which indicate its initial position on a grid. I want to create many instances of this Unit class so as to populate the map.

Here is what I have:

#create units for team 1
#(self, name, x, y, char, color, move_range, atk_range, unit_size, morale, power, fatigue, team)

team_1_cavalry =[(Unit('Cavalry', i+20, 10, 'A', libtcod.yellow, 6, 1, 1000, 100, 1.5, 500, 1)) for i in range(11) ]
team_1_infantry = [(Unit('Heavy Infantry', i+20, 9, '=', libtcod.yellow, 3, 1, 2000, 100, 1.0, 200, 1)) for i in range(11)]
team_1_elephants = [(Unit('War Elephants', 20, 8, 'R', libtcod.yellow, 5, 1, 37, 100, 100, 800, 1)) for i in range(2)]

#create units for team 2
team_2_cavalry = [(Unit('Cavalry', 20+i, 15, 'A', libtcod.green, 6, 1, 500, 1000, 1.5, 500, 2)) for i in range (5)]
team_2_infantry = [(Unit('Roman Infantry', 20+i, 16, '=', libtcod.green, 3, 1, 2000, 100, 1.0, 200, 2)) for i in range(20)]

#the list of objects with those two
team1 = []
team2 = []
for unit in team_1_cavalry, team_1_infantry, team_1_elephants:
    team1.append(unit)
for unit in team_2_cavalry, team_2_infantry:
    team2.append(unit)

teams = [team1, team2]

What I'm trying to do is populate two lists with generated instances of the class. Then iterate over those lists to do various things to the instances therein. However, whenever I try to do anything I get an error saying List object has no attribute [attribute]

I am well aware that I should make each category of unit into a class which inherits from the unit class, I'm just wondering if that is absolutely necessary to make this work and why the way I'm doing it is not working.

Your problem is here:

for unit in team_1_cavalry, team_1_infantry, team_1_elephants:

This is iterating over the tuple team_1_cavalry, team_1_infantry, team_1_elephants . So, first unit is the whole list team_1_cavalry , then it's the whole list team_1_infantry , then it's the whole list team_1_elephants .

What you want is one of the following:

for unit_group in team_1_cavalry, team_1_infantry, team_1_elephants:
    for unit in unit_group:

for unit in team_1_cavalry + team_1_infantry + team_1_elephants:

for unit in itertools.chain(team_1_cavalry, team_1_infantry, team_1_elephants)

The second one is probably the simplest—as long as you're aware that you're making an unnecessary big temporary list, and that this list will always be small enough that there are no performance implications to doing so.


But if you're never actually going to need the three separate lists at all, why even create them? It might be simpler if you just do this:

team_1 = [(Unit('Cavalry', i+20, 10, 'A', libtcod.yellow, 6, 1, 1000, 100, 1.5, 500, 1)) for i in range(11) ]
team_1 += [(Unit('Heavy Infantry', i+20, 9, '=', libtcod.yellow, 3, 1, 2000, 100, 1.0, 200, 1)) for i in range(11)]
team_1 += [(Unit('War Elephants', 20, 8, 'R', libtcod.yellow, 5, 1, 37, 100, 100, 800, 1)) for i in range(2)]

Now, team_1 is just all the units for team 1, of all three kinds.

In:

teams = [team1, team2]

You are building a List of Lists (team1 and team2 are lists).

If you want to create one single list out of 2:

teams = team1 + team2

As you said, you should really consider using classes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM