Esempio n. 1
0
    def __init__(self, space_width, space_height, animal_count, pred_count,
                 genomes):
        self.pool = Pool()
        self.manager = Manager()

        self.width = space_width
        self.height = space_height
        self.genomes = genomes
        self.predators = [
            Predator(random.randrange(0, self.width, 1),
                     random.randrange(0, self.height, 1))
            for _ in range(pred_count)
        ]
        self.animals = [
            Animal(random.choice(genomes), PHEROMONES)
            for _ in range(animal_count)
        ]
        self.objects = [
            Food(random.randrange(0, self.width, 1),
                 random.randrange(0, self.height, 1), 10)
            for _ in range(animal_count)
        ]
        for a in self.animals:
            a.teleport(random.randrange(0, self.width, 1),
                       random.randrange(0, self.height, 1),
                       random.uniform(0, 6.28))
        self.next_food = random.expovariate(1.0 / FOOD_PERIOD)
        self.next_poison = random.expovariate(1.0 / POISON_PERIOD)
        self.pheromones = self.manager.list([])
        self.next_breed = random.expovariate(1.0 / BREEDING_PERIOD)
        self.new_genomes = []
Esempio n. 2
0
 def insert_animal(self, genome):
     a = Animal(genome, PHEROMONES)
     a.teleport(random.randrange(0, self.width, 1),
                random.randrange(0, self.height, 1),
                random.uniform(0, 6.28))
     self.animals.append(a)
     self.objects.append(
         Food(random.randrange(0, self.width, 1),
              random.randrange(0, self.height, 1), 10))
Esempio n. 3
0
	def __init__(self):
		"""
			Initializes a simulation creating the world (which is a grid),
			creating a dictionary of critters, the keys are tuples representing the positions
			and the values are the critters, spawning food and then syncing everything with the
			world
		"""
		self.world = Grid(Environment_s.width, Environment_s.height)
		self.world_age = 0

		self.population = {}
		for i in range(Simulation_s.n_crit):
			c = Critter(Critter_s.randpos())
			self.population[c.pos] = c

		self.food = Food(Simulation_s.n_food)
		self.sync()
Esempio n. 4
0
    def update(self, timestep):

        self.next_food -= timestep
        if self.next_food <= 0.0:
            self.next_food = random.expovariate(1.0 / FOOD_PERIOD)
            self.objects.append(
                Food(random.randrange(0, self.width, 1),
                     random.randrange(0, self.height, 1), 10))

        self.next_poison -= timestep
        if self.next_poison <= 0.0:
            self.next_poison = random.expovariate(1.0 / POISON_PERIOD)
            self.objects.append(
                Poison(random.randrange(0, self.width, 1),
                       random.randrange(0, self.height, 1), 10))

        self.next_breed -= timestep
        if self.next_breed <= 0.0:
            self.next_breed = random.expovariate(1.0 / BREEDING_PERIOD)
            self.animals.sort(key=lambda a: a.energy, reverse=True)
            # choose parents
            parentA = 0
            while random.uniform(0, 1) >= BREEDING_FITNESS:
                parentA += 1
            if parentA >= len(self.animals):
                parentA = len(self.animals) - 1
            parentB = 0
            while random.uniform(0, 1) >= BREEDING_FITNESS:
                parentB += 1
            if parentB >= len(self.animals):
                parentB = len(self.animals) - 1
            # breed
            self.new_genomes.append(
                self.pool.apply_async(breed,
                                      (self.animals[parentA].brain.genome,
                                       self.animals[parentB].brain.genome)))

        if len(self.new_genomes) > 0 and self.new_genomes[0].ready():
            new_genome = self.new_genomes.pop(0)
            child = Animal(new_genome.get(), PHEROMONES)
            child.teleport(random.randrange(0, self.width, 1),
                           random.randrange(0, self.height, 1),
                           random.uniform(0, 6.28))
            self.animals.append(child)

        result = list(
            zip(*(a for a in self.pool.starmap(update_animal, (
                (a, self.pheromones, timestep, self.width, self.height)
                for a in self.animals)))))
        self.animals = [a for a in result[0] if a.energy > 0]
        for fl in result[1]:
            self.pheromones.extend(fl)

        for f in self.objects:
            f.update(self.animals, self.pheromones, timestep)

        for p in self.predators:
            p.update(self.animals, self.pheromones, timestep, self.width,
                     self.height)

        for f in self.pheromones:
            f.tick(timestep)

        # remove finished foods
        self.objects = [f for f in self.objects if f.amount > 0.0]
        # remove vanished pheromones
        self.pheromones = [f for f in self.pheromones if f.power() > 0.1]
Esempio n. 5
0
class Simulation:
	def __init__(self):
		"""
			Initializes a simulation creating the world (which is a grid),
			creating a dictionary of critters, the keys are tuples representing the positions
			and the values are the critters, spawning food and then syncing everything with the
			world
		"""
		self.world = Grid(Environment_s.width, Environment_s.height)
		self.world_age = 0

		self.population = {}
		for i in range(Simulation_s.n_crit):
			c = Critter(Critter_s.randpos())
			self.population[c.pos] = c

		self.food = Food(Simulation_s.n_food)
		self.sync()

	def sync(self):
		"""
			Overlaps the current grid world with the updated one
		"""
		self.world = Grid(Environment_s.width, Environment_s.height)

		for pos in self.food.food:
			self.world.set_value(pos[0], pos[1], Environment_s.grid_food)

		for pos in self.population.keys():
			self.world.set_value(pos[0], pos[1], Environment_s.grid_crit)

	def step(self):
		"""
			Makes the population move by one step, reproduce according to the constraints and
			will, increase world's age, spawn new food and update the world
		"""
		children = []
		critters = self.population.values()
		old_pos  = self.population.keys()
		
		for crit in critters:
			self.world.set_value(crit.pos[0], crit.pos[1], Environment_s.grid_void)	# clear the space on the world 
			
			sub = self.world.sub_grid(crit.pos)						# critter's view
			partners_pos = sub.get_type(Environment_s.grid_crit)	# relative position of the potential partners
			partners = []											# potential partners

			for pos in partners_pos:
				pos = (crit.pos[0]+pos[0] - Critter_s.sight, crit.pos[1]+pos[1] - Critter_s.sight)	# absolute position of the partner
				partners.append(self.population[pos])

			old_pos  = crit.pos
			children += crit.process(self.world, partners)

			if self.food.food.has_key(crit.pos):
				crit.eat(self.food.food.pop(crit.pos))	# removes the food from the food list and increments the energy of the critter
				self.world.set_value(crit.pos[0], crit.pos[1], Environment_s.grid_void) # removes the food from the world

			self.population.pop(old_pos)	# removes critter from old position
			if not crit.is_dead():
				if self.population.has_key(crit.pos):
					crit.pos = old_pos				# if the new position is occupied by another critter don't move
				self.population[crit.pos] = crit 	# set critter in the new (or old) position
				self.world.set_value(crit.pos[0], crit.pos[1], Environment_s.grid_crit)	# updates the world 

		self.add_children(children)				# add children in the population list
		self.world_age += 1						# increments world's age
		self.food.add(1, None, self.world_age)	# spawns randomly 1 food
		self.sync()

	def add_children(self, children):
		"""
			Adds the given children on the population list of the simulation

			Parameter children is a list of critters
		"""
		for child in children:
			if not self.population.has_key(child.pos):
				self.population[child.pos] = child

	def min_stat(self, field):
		"""
			Returns the critter with the lowest value of field
			or None if the population is empty

			Parameter field is a string indicating the attribute to compare
		"""
		l = [(getattr(c, field), c) for c in self.population.values()] # tuples with (value, critter)
		return min((l, [(None, None)])[l == []])[1]

	def max_stat(self, field):
		"""
			Returns the critter with the highest value of field
			or None if the population is empty

			Parameter field is a string indicating the attribute to compare
		"""
		l = [(getattr(c, field), c) for c in self.population.values()] # tuples with (value, critter)
		return max((l, [(None, None)])[l == []])[1]
		
	def sum_stat(self, field):
		"""
			Returns the sum of the values in field of the whole population 
			or 0 if the population is empty

			Parameter field is a string indicating the attribute to sum
		"""
		l = [getattr(c, field) for c in self.population.values()] # list of values
		return sum((l, [0])[l == []])
		
	def average_stat(self, field):
		"""
			Returns the average of the values in field of the whole population
			or 0 if the population is empty

			Parameter field is a string indicating the attribute to average
		"""
		return float(self.sum_stat(field))/(len(self.population), 1)[len(self.population) == 0]

#########temporary until new gui#############
	def stats(self):
		"""
			Statistics sample
			Returns a string with some informations about the world and about the population
		"""
		max_energy = self.max_stat("energy")
		min_energy = self.min_stat("energy")
		oldest = self.max_stat("age")
		average_age = self.average_stat("age")
		average_energy = self.average_stat("energy")
	
		if max_energy == None or min_energy == None or oldest == None:
			return ["World age: " + str(self.world_age), 
				 	"Food quantity: " + str(len(self.food.food))]
		stats = [str(len(self.population)) + " critters.",
				 "World age: " + str(self.world_age), 
				 "Food quantity: " + str(len(self.food.food)),
				 "Max energy critter[" + str(max_energy) + "]",
				 "Min energy critter[" + str(min_energy) + "]",
				 "Oldest critter[" + str(oldest) + "]",
				 "Average age: " + str(average_age),
				 "Average energy: " + str(average_energy)
				 ]
		return stats