def test_get_cell_edible(): """ Test that the mushroom is returned if cell occupied """ env = Environment(1, 1, 0, 1) assert environment.is_edible(env.get_cell((0, 0)))
def test_get_cell_empty(): """ Test that 0 is returned if cell empty """ env = Environment(1, 1, 0, 0) assert env.get_cell((0, 0)) == 0
def test_random_available_position(): """ Check that the closest mushroom is correctly returned """ env = Environment(10, 10, 40, 40) for _ in range(10): assert env.get_cell(env.random_available_position()) == 0
def test_clear_cell(): """ Test that a cell is cleared """ env = Environment(1, 1, 1, 0) env.clear_cell((0, 0)) assert env.get_cell((0, 0)) == 0 assert len(env.world) == 0
def run_single(self, entity, population=[], viewer=False): """ Runs a single simulation for one entity Runs num_epochs epochs, each of which contains num_cycles time steps. At each time step, the world is updated according to the behaviour of the entity. The entity returns an action given inputs that depend on its position in the simulated world. Args: entity: The entity whose behaviour is tested at each step. population: The remaining entities in the population viewer (bool): If true, prints debugging information and pauses """ env = Environment() env.place_entity() if viewer: print("Entity weights: \n", entity.weights) print("Entities biases: \n", entity.biases) # Run num_epochs epochs of num_cycles cycles each for epoch in range(self.num_epochs): # Store previous actions for optimisations previous_actions = [] for step in range(self.num_cycles): # Get entity position and closest mushroom entity_pos = env.get_entity_position() try: mush_pos = env.closest_mushroom(entity_pos) except environment.MushroomNotFound: # Skip cycle if all mushrooms have been eaten break # Calculate the angle and get mushroom properties if close enough angle = env.get_entity_angle_to_position(mush_pos) mush = env.get_cell(mush_pos) if env.adjacent(entity_pos, mush_pos) else 0 # Get audio signal according to language type signal = self.get_signal(angle, env.get_cell(mush_pos), population, viewer) # Get the behaviour of the entity given perceptual inputs action, out_signal = entity.behaviour(angle, mush, signal) # Print debug information if viewer: to_print = "\n".join([ "Epoch: {0} Cycle: {1}".format(epoch, step), str(env), "Entity fitness: {0}".format(entity.fitness), "Entity position: ({0},{1})".format(entity_pos[0], entity_pos[1]), "Closest mushroom position: ({0},{1})".format(mush_pos[0], mush_pos[1]), "Direction: {0}".format(env.entity_direction), "Angle: {0}".format(angle), "Mushroom input: {0}".format(mush), "Signal input: {0}".format(signal), "Action chosen: {0}".format(action), "Signal output: {0}".format(out_signal) ]) print(to_print) ##time.sleep(0.1) usr_input = input() if usr_input == chr(27): return entity # If the action is NOTHING, it will stay that way, # so we can make some optimisations if self.skip_none and action == Action.NOTHING: break # We can also break if the entity tries to move forward but can't if self.skip_facing_out and action == Action.FORWARDS and env.entity_facing_out(): break # Detect if the entity is spinning forever by examining previous three actions if self.detect_looping: previous_actions.append(action) if step > 2: if action in [Action.LEFT, Action.RIGHT]: looping = True for prev in previous_actions: if prev != action: looping = False if looping: break previous_actions = previous_actions[1:4] # Do the action env.move_entity(action) # Finally, eat a mushroom if currently on one new_pos = env.get_entity_position() if env.is_mushroom(new_pos): entity.eat(env.get_cell(new_pos)) env.clear_cell(new_pos) if viewer: print("EATING MUSHROOM") # After an epoch, reset the world and replace the entity env.reset() env.place_entity() return entity