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 __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()
# 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)
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