Beispiel #1
0
	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)
Beispiel #2
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()
Beispiel #3
0
# TO DO: Make it work with (3,4) q table size
# Remove redundant initialization of params
'''
Agent starts at bottom left and needs to make its
way to the top right
'''

import numpy as np
from environment import Grid
from agent import Agent
import random
import matplotlib.pyplot as plt

if __name__ == '__main__':

    grid = Grid(5, 5)
    agent = Agent()
    num_episodes = 5000
    num_steps = 99

    gamma = 0.7
    alpha = 0.610

    epsilon = 1
    max_epsilon = 1
    min_epsilon = 0.01
    decay_rate = 0.01

    def step(action, current_state):

        previous_state_position = grid.state_to_position(current_state)
Beispiel #4
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