I’m using Python to make a simple evolution simulator.
There is a list called engine.All, that stores both the units/animals and food. I iterate through it, and if I run into an animal, I iterate through it once again to find if he is colliding with any of the food pieces.
If so, then I increase his energy, flag the food piece as eaten, and add it to the toRemove list, which I later use to remove the elements from engine.All.
This is the code, but with all redundant things removed:
def remove(l, who): #This should remove all the elements contained in who from the list l
offset = 0
for i in who:
l.pop(i + offset)
offset -= 1
return l
for ob in engine.All:
if ob.skip:
continue;
if ob.drawable:
ob.draw()
if isinstance(ob, Flatlander): #If it is an animal
#Do speed stuff
ob.energy -= decay #Lower its energy
for i in range(len(engine.All)): #Iterate through the list again
if collides(ob.pos, ob.r, engine.All[i].pos, engine.All[i].r) and isinstance(engine.All[i], Food) and ob.energy + engine.All[i].r < ob.r**2*3.14 and not engine.All[i].skip: #If it collides with a food piece, the food piece isn't about to be deleted and it can take the energy in (their maximum is defined by their radiuses)
ob.energy += engine.All[i].r #Increase the his energy
toRemove.append(i) #Add the food piece to the toRemove list
engine.All[i].skip = True #Flag it as skipped
if ob.energy < 0 and not ob.skip: #If its energy is 0 and if it isn't already about to be deleted
toRemove.append(engine.All.index(ob)) #Add it to the toRemove list
ob.skip = True #Flag it as skipped
engine.All = remove(engine.All, toRemove)
I am almost certain that this doesn’t work, and that there is a better way of doing this. The reason I’m so certain is that sometimes, I see things just “flashing” on the screen – suddenly disappearing and appearing again. Also, there seem to be “ghost” animals (referred to as Flatlanders in the code), I conclude this because sometimes the food pieces are disappearing permanently.
Please, recommend a way of doing this that is more efficient.
If the
skipattribute is only set for those objects which need to be removed, just make use of that:Generally I would probably prefer to keep the food items and the flatlanders in separate lists.
There are several technique for doing collision detection more efficiently (for example dividing the world into squares, and checking only those animals in the same or surrounding squares) but if you have only a few (say less than a few hundred) animals/food items this will not be needed.