def test_commit(self): ''' test local portion of commit operations (create env.to_remote) ''' self.args.new = True self.args.delete = False self.args.list = ['a_new_list'] self.args.type = 'block' self.args.action = 'block' self.args.match = 'exact' self.args.variable = None self.args.block_length = None # create a new environment, populate it with our list env = Environment(self.args) env.mock_remote = True Lists(self.args, env) # add items to the list self.args.add = True self.args.remove = False self.args.clean = False self.args.removeall = False self.args.item = ['!10.0.0.0/8'] self.args.file = None Items(self.args, env) self.args.item = ['2a04:4e42:10::313/128'] Items(self.args, env) # commit to 'remote' service State().commit(env, 'remote') # ensure SERVICEID is copied into env.to_remote self.assertEqual(env.to_remote['service_id'], 'SERVICEID') # ensure snippet contains config block and logic for our list self.assertRegex( env.to_remote['snippet']['content'], r'\n#fastlyblocklist_list {"name": "a_new_list".*"items": \[\]}\n') self.assertRegex( env.to_remote['snippet']['content'], r'\n\s*if \(var\.ip ~ fastlyblocklist_a_new_list\) {\n') # ensure our list is converted to ACL self.assertEqual(env.to_remote['acls'][0]['name'], 'fastlyblocklist_a_new_list') self.assertEqual(env.to_remote['acls'][0]['items'][0]['ip'], '10.0.0.0') self.assertEqual(env.to_remote['acls'][0]['items'][0]['negated'], '1') self.assertEqual(env.to_remote['acls'][0]['items'][0]['subnet'], 8) self.assertEqual(env.to_remote['acls'][0]['items'][1]['ip'], '2a04:4e42:10::313') self.assertEqual(env.to_remote['acls'][0]['items'][1]['negated'], '0') self.assertEqual(env.to_remote['acls'][0]['items'][1]['subnet'], 128)
def draw_maps(self): # Render nutrientmap currently in view self.map_surface.fill(UI.BACKGROUND_COLOUR) for x in range( self.camera_offset[0], round(screen_dimensions_without_hud[0] / Constants.ENVIRONMENT_ZONE_SIZE) + self.camera_offset[0]): for y in range( self.camera_offset[1], round(screen_dimensions_without_hud[1] / Constants.ENVIRONMENT_ZONE_SIZE) + self.camera_offset[1]): pygame.draw.rect( self.map_surface, Environment.get_colour(self.nutrientmap[x][y], self.heatmap[x][y], self.moisturemap[x][y]), ((x - self.camera_offset[0]) * Constants.ENVIRONMENT_ZONE_SIZE, (y - self.camera_offset[1]) * Constants.ENVIRONMENT_ZONE_SIZE, Constants.ENVIRONMENT_ZONE_SIZE, Constants.ENVIRONMENT_ZONE_SIZE)) if self.toggle: Text.draw_text((x - self.camera_offset[0]) * Constants.ENVIRONMENT_ZONE_SIZE, (y - self.camera_offset[1]) * Constants.ENVIRONMENT_ZONE_SIZE, str(round(self.heatmap[x][y])), UI.TEXT_SIZE, (255, 90, 0), self.map_surface)
def test_new_list_none(self): ''' try to create a valid new list with action none ''' self.args.new = True self.args.delete = False self.args.list = ['a_new_list'] self.args.type = 'block' self.args.action = 'none' self.args.match = None self.args.variable = None self.args.block_length = None # create a new environment env = Environment(self.args) # create a new list Lists(self.args, env) self.assertEqual(len(env.config['lists']), 1) self.assertEqual(env.config['lists'][0]['name'], 'a_new_list') self.assertEqual(env.config['lists'][0]['type'], 'block') self.assertEqual(env.config['lists'][0]['action_none'], True) self.assertEqual(env.config['lists'][0]['action_block'], False)
def test_load_config(self): ''' test init and load of a config file ''' # create a new config file Environment(self.args) # load an existing config file self.args.init = False env = Environment(self.args) # ensure apikey and config are populated self.assertEqual(env.apikey, 'MYTESTAPIKEY') self.assertTrue(env.config['services']) self.assertFalse(env.config['lists']) self.assertEqual(env.config['log'], '')
def test_load_config_override_services(self): ''' test runtime override of args.services ''' # create a new config file Environment(self.args) # load an existing config file and replace services in running config self.args.init = False self.args.service = ['SERVICE1', 'SERVICE2'] env = Environment(self.args) # ensure override services are targeted self.assertEqual( len(env.config['services']), 2 )
def test_init_service_defaults(self): ''' ensure service config defaults are set during init ''' # create a new environment env = Environment(self.args) # ensure service defaults self.assertEqual(env.config['services'][0]['type'], 'recv') self.assertEqual(env.config['services'][0]['priority'], '10') self.assertEqual(env.config['services'][0]['options']['edge_only'], True) self.assertEqual(env.config['services'][0]['options']['var_ip'], 'client.ip')
def test_init(self): ''' test init of a new config file ''' # create a new environment env = Environment(self.args) # ensure apikey and config are populated self.assertEqual(env.apikey, 'MYTESTAPIKEY') self.assertTrue(env.config['services']) self.assertFalse(env.config['lists']) self.assertEqual(env.config['log'], '')
def test_save_config(self): ''' test saving a config file ''' # create a new config file Environment(self.args) # load existing config file, change something, and save self.args.init = False self.args.service = ['SERVICE1', 'SERVICE2'] Environment(self.args).save_config() # load the modified config file self.args.service = [] env = Environment(self.args) # ensure updated config is loaded self.assertEqual( len(env.config['services']), 2 )
def test_load_config_auto_generate(self): ''' test init of a new config file where args.init is not provided ''' # auto init a config file when one doesn't exist self.args.init = False env = Environment(self.args) # ensure apikey and config are populated self.assertEqual(env.apikey, 'MYTESTAPIKEY') self.assertTrue(env.config['services']) self.assertFalse(env.config['lists']) self.assertEqual(env.config['log'], '')
def test_save(self): ''' test create, save, and load of a config file ''' # create a new config file Environment(self.args) # load existing config file, change something self.args.init = False self.args.save = True self.args.service = ['SERVICE1', 'SERVICE2'] env = Environment(self.args) # save the changes using State().save() State().save(env) # load the modified config file self.args.service = [] env = Environment(self.args) # ensure updated config is loaded self.assertEqual(len(env.config['services']), 2)
def test_init_config_exists(self): ''' test init of a new config file where another exists ''' # create a 'valid' config file with open('tests.blocklist', 'w') as file_apikey: file_apikey.write('{}') # try to create a new config over existing self.args.force = False with self.assertRaisesRegex( SystemExit, "config file exists" ): Environment(self.args)
def test_new_list_var_bad(self): ''' try to create a new var list where no args.variable provided ''' self.args.new = True self.args.delete = False self.args.list = ['a_new_list'] self.args.type = 'var' self.args.action = 'block' self.args.match = 'exact' self.args.variable = None self.args.block_length = None # create a new environment env = Environment(self.args) with self.assertRaisesRegex(SystemExit, "no list variable defined"): Lists(self.args, env)
def test_init_config_exists_force(self): ''' test init of a new config file where another exists and args.force is provided ''' # create a 'valid' config file with open('tests.blocklist', 'w') as file_apikey: file_apikey.write('{}') # force create a new config over existing self.args.force = True env = Environment(self.args) # ensure apikey and config are populated self.assertEqual(env.apikey, 'MYTESTAPIKEY') self.assertTrue(env.config['services']) self.assertFalse(env.config['lists']) self.assertEqual(env.config['log'], '')
def test_new_list_temp(self): ''' try to create a valid new temp list ''' self.args.new = True self.args.delete = False self.args.list = ['a_new_list'] self.args.type = 'temp' self.args.action = 'block' self.args.match = None self.args.variable = None self.args.block_length = 600 # create a new environment env = Environment(self.args) Lists(self.args, env) self.assertEqual(len(env.config['lists']), 1) self.assertEqual(env.config['lists'][0]['type'], 'temp') self.assertEqual(env.config['lists'][0]['block_length'], 600)
def test_new_list_var(self): ''' try to create a valid new var list ''' self.args.new = True self.args.delete = False self.args.list = ['a_new_list'] self.args.type = 'var' self.args.action = 'block' self.args.match = 'exact' self.args.variable = 'req.whatever' self.args.block_length = None # create a new environment env = Environment(self.args) Lists(self.args, env) self.assertEqual(len(env.config['lists']), 1) self.assertEqual(env.config['lists'][0]['type'], 'var') self.assertEqual(env.config['lists'][0]['match'], 'exact') self.assertEqual(env.config['lists'][0]['variable'], 'req.whatever')
def test_delete_list(self): ''' try to create and delete a valid list ''' self.args.new = True self.args.delete = False self.args.list = ['a_new_list'] self.args.type = 'var' self.args.action = 'block' self.args.match = 'exact' self.args.variable = 'req.whatever' self.args.block_length = None # create a new environment env = Environment(self.args) Lists(self.args, env) self.args.new = False self.args.delete = True Lists(self.args, env) self.assertFalse(env.config['lists'])
def test_delete_list_bad(self): ''' try to delete a list where no args.list provided ''' self.args.new = True self.args.delete = False self.args.list = ['a_new_list'] self.args.type = 'var' self.args.action = 'block' self.args.match = 'exact' self.args.variable = 'req.whatever' self.args.block_length = None # create a new environment env = Environment(self.args) Lists(self.args, env) self.args.new = False self.args.delete = True self.args.list = [] with self.assertRaisesRegex(SystemExit, r"no list name\(s\) defined"): Lists(self.args, env)
def __init__(self, thread_name, thread_type, parameter_server, rhost): self.environment = Environment( thread_name, thread_type, parameter_server, rhost) self.thread_name = thread_name self.thread_type = thread_type self.util = Utilty()
class Worker_thread: def __init__(self, thread_name, thread_type, parameter_server, rhost): self.environment = Environment( thread_name, thread_type, parameter_server, rhost) self.thread_name = thread_name self.thread_type = thread_type self.util = Utilty() # Execute learning or testing. def run(self, exploit_tree, target_tree, saver=None, train_path=None): self.util.print_message( NOTE, 'Executing start: {}'.format(self.thread_name)) while True: if self.thread_type == 'learning': # Execute learning thread. self.environment.run(exploit_tree, target_tree) # Stop learning thread. if isFinish: self.util.print_message( OK, 'Finish train: {}'.format(self.thread_name)) time.sleep(3.0) # Finally save learned weights. self.util.print_message( OK, 'Save learned data: {}'.format(self.thread_name)) saver.save(SESS, train_path) # Disconnection RPC Server. self.environment.env.client.termination( self.environment.env.client.console_id) if self.thread_name == 'local_thread1': # Create plot. df_plot = pd.DataFrame({'exploitation': plot_count, 'post-exploitation': plot_pcount}) df_plot.to_csv(os.path.join( self.environment.env.data_path, 'experiment.csv')) # df_plot.plot(kind='line', title='Training result.', legend=True) # plt.savefig(self.environment.env.plot_file) # plt.close('all') # Create report. report = CreateReport() report.create_report('train', pd.to_datetime( self.environment.env.scan_start_time)) break else: # Execute testing thread. self.environment.run(exploit_tree, target_tree) # Stop testing thread. if isFinish: self.util.print_message(OK, 'Finish test.') time.sleep(3.0) # Disconnection RPC Server. self.environment.env.client.termination( self.environment.env.client.console_id) # Create report. report = CreateReport() report.create_report('test', pd.to_datetime( self.environment.env.scan_start_time)) break
while action is None: try: action = input('what should I do? {} >>> '.format(actions)) if action == 'quit': return True agent.step(action) except ValueError: action = None return False if __name__ == '__main__': # define the gridworld environment env = Environment([ [-10,0,0,50], [0,10,100, 0, -100, 500], [0,0, None, 10, None, -10, None], [None,0, 5, 10, None, 5, 0] ]) # start at a random position pos = random.choice(env.positions) # simple reward function def reward(state): return env.value(state) # try discount=0.1 and discount=0.9 DISCOUNT = 0.1 LEARNING_RATE = 1 agent = QLearner(pos, env, reward, discount=DISCOUNT, learning_rate=LEARNING_RATE) env.render(agent.state)
def test_sync(self): ''' test local portion of sync operations (env.from_remote to env.config) ''' # create a new environment env = Environment(self.args) env.mock_remote = True # create an env.from_remote object env.from_remote = { 'service_id': 'REMOTESERVICEID', 'version': 1, 'snippet': { 'name': 'REMOTE_SNIPPET_NAME', 'type': 'recv', 'priority': 10, 'content': '#fastlyblocklist_list {"name": "my_test_list", ' '"type": "block", "action_block": true, ' '"action_log": true, "action_none": false, ' '"match": "exact", "variable": null, ' '"block_length": 600, "items": []}\n' }, 'acls': [{ 'name': 'fastlyblocklist_my_test_list', 'items': [{ 'comment': '', 'subnet': 8, 'service_id': 'REMOTESERVICEID', 'negated': '1', 'deleted_at': None, 'ip': '10.0.0.0' }, { 'comment': '', 'subnet': None, 'service_id': 'REMOTESERVICEID', 'negated': '0', 'deleted_at': None, 'ip': '2a04:4e42:10::313' }] }], 'dicts': [] } # sync env.from_remote to local env.config State().sync(env, 'remote') # ensure remote made it into our local config self.assertEqual(env.config['services'][0]['id'], 'REMOTESERVICEID') self.assertEqual(env.config['services'][0]['snippet_name'], 'REMOTE_SNIPPET_NAME') self.assertEqual(env.config['lists'][0]['name'], 'my_test_list') self.assertEqual(env.config['lists'][0]['type'], 'block') self.assertTrue(env.config['lists'][0]['action_block']) self.assertEqual(env.config['lists'][0]['items'][0], '!10.0.0.0/8') self.assertEqual(env.config['lists'][0]['items'][1], '2a04:4e42:10::313/128')
action = None while action is None: try: action = input('what should I do? {} >>> '.format(actions)) if action == 'quit': return True agent.step(action) except ValueError: action = None return False if __name__ == '__main__': # define the gridworld environment env = Environment([[-10, 0, 0, 50], [0, 10, 100, 0, -100, 500], [0, 0, None, 10, None, -10, None], [None, 0, 5, 10, None, 5, 0]]) # start at a random position pos = random.choice(env.positions) # simple reward function def reward(state): return env.value(state) # try discount=0.1 and discount=0.9 DISCOUNT = 0.1 LEARNING_RATE = 1 agent = QLearner(pos, env, reward,
def gameloop(self): while not self.done: while not self.done and Globals.titlescreen: #For Multiple gameloops subsets. For example, a title screen and a pause screen title_events = pygame.event.get() for title_event in title_events: #Event handling if title_event.type == pygame.QUIT: self.done = True if title_event.type == pygame.KEYDOWN: if title_event.key == K_x: pass if title_event.type == pygame.KEYUP: if title_event.key == K_x: pass if title_event.type == pygame.MOUSEBUTTONDOWN: if title_event.button == 1: for button in self.buttons: if button.hovered: button.activate() if button.__class__ == Button.NewButton: ''' An important block of code! It is run ONCE when the "New Simulation" button is pressed. You will find environment generation, etc. here ''' self.buttons.clear() print("Generating environment...") gen_hmap_start_time = time() self.nutrientmap = Environment.generate_noisemap( Constants.MAP_WIDTH, Constants.MAP_HEIGHT) self.heatmap = Environment.generate_noisemap( Constants.MAP_WIDTH, Constants.MAP_HEIGHT, Constants.HEATMAP_MULTIPLER ) # Less intense heatmap self.moisturemap = Environment.generate_noisemap( Constants.MAP_WIDTH, Constants.MAP_HEIGHT) self.regenmap = Environment.generate_noisemap( Constants.MAP_WIDTH, Constants.MAP_HEIGHT, 1 / Constants.REPLENISH_DIVISOR) gen_hmap_end_time = time() print("Done. Took " + str(gen_hmap_end_time - gen_hmap_start_time) + " seconds.") del gen_hmap_start_time, gen_hmap_end_time print("Rendering environment...") rend_hmap_start_time = time() self.draw_maps() rend_hmap_end_time = time() print("Done. Took " + str(rend_hmap_end_time - rend_hmap_start_time) + " seconds.") del rend_hmap_start_time, rend_hmap_end_time for i in range( Constants.STARTING_POPULATION): self.organisms.append( self.generate_random_organism( )) self.organisms[-1].limit_position() mainscreen_timestamp = time() respawn_timestamp = time() #Titlescreen logic below screen.fill(UI.BACKGROUND_COLOUR) for button in self.buttons: button.update() button.draw() pygame.display.flip() #Updates display clock.tick(60) while not self.done and not Globals.titlescreen and Globals.mainscreen: main_events = pygame.event.get() for main_event in main_events: #Event handling if main_event.type == pygame.QUIT: self.done = True if main_event.type == pygame.KEYDOWN: if main_event.key == K_x: pass if main_event.key == K_UP: # self.organisms[0].acceleration[0] = -1 pass if main_event.key == K_DOWN: # self.organisms[0].acceleration[0] = 1 pass if main_event.key == K_RIGHT: # self.organisms[0].rotational_acceleration = -1 pass if main_event.key == K_LEFT: # self.organisms[0].rotational_acceleration = 1 pass if main_event.key == K_k: self.toggle *= -1 self.toggle += 1 if main_event.key == K_w: if self.camera_offset[1] > 0: self.camera_offset[1] -= 1 self.draw_maps() if main_event.key == K_a: if self.camera_offset[0] > 0: self.camera_offset[0] -= 1 self.draw_maps() if main_event.key == K_s: if self.camera_offset[ 1] < Constants.MAP_HEIGHT - round( screen_dimensions_without_hud[1] / Constants.ENVIRONMENT_ZONE_SIZE): self.camera_offset[1] += 1 self.draw_maps() if main_event.key == K_d: if self.camera_offset[ 0] < Constants.MAP_WIDTH - round( screen_dimensions_without_hud[0] / Constants.ENVIRONMENT_ZONE_SIZE): self.camera_offset[0] += 1 self.draw_maps() if main_event.type == pygame.KEYUP: if main_event.key == K_x: pass if main_event.type == pygame.MOUSEBUTTONDOWN: if main_event.button == 1: '''mousepom = self.position_to_map_position(pygame.mouse.get_pos(), True) print("mouse pom", mousepom) self.heatmap[mousepom[0]][mousepom[1]] = 1000000''' for organism in self.organisms: if pygame.Rect.colliderect( pygame.Rect( self.position_to_screen_position( organism.get_hitbox())), (pygame.mouse.get_pos()[0], pygame.mouse.get_pos()[1], 1, 1)): self.target_organism = organism for button in self.buttons: if button.hovered: button.activate() # Mainscreen logic below screen.fill(UI.BACKGROUND_COLOUR) screen.blit(self.map_surface, (0, 0)) current_time = time() if len( self.organisms ) < Constants.POPULATION_MINIMUM and current_time - respawn_timestamp >= Constants.RESPAWN_DELAY: for i in range(Constants.POPULATION_MINIMUM - len(self.organisms)): self.organisms.append(self.generate_random_organism()) self.organisms[-1].limit_position() respawn_timestamp = time() if current_time - mainscreen_timestamp >= Constants.MAP_REFRESH_DELAY: # Delete the dead organisms and re-render the map every few seconds # Also give energy to the map so the organisms have an energy source for organism in self.organisms[:]: if organism.get_dead(): self.organisms.remove(organism) mainscreen_timestamp = time() for x in range(Constants.MAP_WIDTH): for y in range(Constants.MAP_HEIGHT): if self.nutrientmap[x][ y] < Constants.ENVIRONMENT_SCALING: self.nutrientmap[x][y] += self.regenmap[x][y] self.draw_maps() for button in self.buttons: button.update() button.draw() qt_width = Constants.MAP_WIDTH * Constants.ENVIRONMENT_ZONE_SIZE qt_height = Constants.MAP_HEIGHT * Constants.ENVIRONMENT_ZONE_SIZE self.quadtree = Quadtree.Quadtree( Quadtree.CentreRect(qt_width / 2, qt_height / 2, qt_width, qt_height), Constants.QUADTREE_CAPACITY) del qt_width, qt_height for organism in self.organisms: pom = self.position_to_map_position(organism.get_hitbox()) if not organism.get_dead(): organism.update(self.heatmap[pom[0]][pom[1]], self.moisturemap[pom[0]][pom[1]]) # Make the organism eat if in a neutral mood if organism.get_mood_name() == "Neutral": if self.nutrientmap[pom[0]][pom[1]] > 0: organism.shift_energy( organism.get_size() * Constants.EAT_GAIN_MULTIPLIER) self.nutrientmap[pom[0]][ pom[1]] -= organism.get_size( ) #*Constants.EAT_GAIN_MULTIPLIER organism_map_position = self.position_to_map_position( organism.get_position()) organism.make_decision([], [ self.nutrientmap[organism_map_position[0]][ organism_map_position[1]], self.heatmap[organism_map_position[0]][ organism_map_position[1]], self.moisturemap[organism_map_position[0]][ organism_map_position[1]] ]) organism.draw(screen, [ o * Constants.ENVIRONMENT_ZONE_SIZE for o in self.camera_offset ]) self.quadtree.insert( (organism.get_position()[0], organism.get_position()[1], organism)) if self.toggle: self.quadtree.draw(screen, [ o * Constants.ENVIRONMENT_ZONE_SIZE for o in self.camera_offset ]) for organism in self.organisms: vision_collide_points = self.quadtree.query( Quadtree.NormalRect( organism.get_vision_hitbox_points())) organism_collide_points = self.quadtree.query( Quadtree.NormalRect(organism.get_hitbox_points())) colliding_organisms = [ o[2] for o in organism_collide_points ] seen_organisms = [o[2] for o in vision_collide_points] for other_organism in colliding_organisms: organism.bump(other_organism.get_velocity()[0]) if organism != other_organism: if organism.get_aggression( ) or other_organism.get_aggression(): # Attack if organism.get_aggression( ) and other_organism.get_aggression(): # Both organisms take damage and gain energy organism.shift_fitness( -other_organism.get_attack()) other_organism.shift_fitness( -organism.get_attack()) organism.shift_energy( organism.get_attack()) other_organism.shift_energy( other_organism.get_attack()) else: for o in [organism, other_organism]: if not o.get_aggression: # o takes damage, and the other gets energy o.fitness -= [ organism, other_organism ][[organism, other_organism].index( o) - 1].get_attack() [[organism, other_organism ].index(o) - 1].shift_energy([ [organism, other_organism ].index(o) - 1 ].get_attack()) elif organism.get_mating( ): # and other_organism.get_mating(): # Reproduce if len(self.organisms ) < Constants.POPULATION_LIMIT: organism.shift_energy( -organism.get_size() * Constants.REPRODUCTION_COST_MULTIPLIER) other_organism.shift_energy( -other_organism.get_size() * Constants.REPRODUCTION_COST_MULTIPLIER) average_energy_loss = ( (organism.get_size() * Constants. REPRODUCTION_COST_MULTIPLIER) + (other_organism.get_size() * Constants. REPRODUCTION_COST_MULTIPLIER)) // 2 average_position = [ (p1 + p2) / 2 for p1, p2 in zip( organism.get_position(), other_organism.get_position()) ] pc = (organism.get_point_count() + other_organism.get_point_count() ) // 2 + round(random() - 0.3) * randint(-1, 1) minpc = min( organism.get_point_count(), other_organism.get_point_count()) if pc > minpc: # Need extra arm stats ac = [ (organism.get_arm_chances()[i] + other_organism.get_arm_chances() [i]) / 2 for i in range(minpc) ] ac += [ random() for i in range(pc - minpc) ] else: # We're good ac = [ (organism.get_arm_chances()[i] + other_organism.get_arm_chances() [i]) / 2 for i in range(pc) ] minaco = min( len(organism.get_arms()), len(other_organism.get_arms())) astr = [ (organism.get_arm_strengths()[i] + other_organism.get_arm_strengths()[i]) / 2 for i in range(minaco) ] if pc > minaco: # Need extra arm strengths astr += [ random() for i in range(pc - minaco) ] '''print("repro point count: ", pc) print("repro chances: ", len(ac)) print("repro strengths: ", len(astr))''' average_gene_dict = { "colour": tuple([(c1 + c2) / 2 for c1, c2 in zip( organism.get_colour(), other_organism.get_colour())]), "point_count": pc, "arm_chances_per_point": ac, "arm_strength_per_arm": astr, "size": (organism.get_size() + other_organism.get_size()) // 2 + round(random() - 0.3) * randint(-1, 1), "behaviour_bias": (organism.get_behaviour_bias() + other_organism.get_behaviour_bias()) / 2 + (random() * 2 - 1) / 8, "temp_regulator": (organism.get_temp_regulator() + other_organism.get_temp_regulator()) / 2 + (random() * 2 - 1) / 8, "input_weights": [ (iw1 + iw2) / 2 + (random() * 2 - 1) / 8 for iw1, iw2 in zip( organism.get_input_weights(), other_organism. get_input_weights()) ], "hidden_weights": [ (hw1 + hw2) / 2 + (random() * 2 - 1) / 8 for hw1, hw2 in zip( organism.get_hidden_weights(), other_organism. get_hidden_weights()) ], "output_weights": [ (ow1 + ow2) / 2 + (random() * 2 - 1) / 8 for ow1, ow2 in zip( organism.get_input_weights(), other_organism. get_input_weights()) ] } # (random()*2 - 1) / 8 is a weight mutation. This value should be studied closely, as it is the "step size" for the neural net average_generation = max([ organism.get_generation(), other_organism.get_generation() ]) + 1 average_id = min( organism.get_id(), other_organism.get_id() ) # Someone's id has to win out. I'll use the lower one #print("repro id: ", average_id) # Pick a polygon at random for the child. average_polygon = [ organism.get_original_polygon(), other_organism.get_original_polygon() ][randint(0, 1)] # Finally, the offspring is created! self.organisms.append( Organism.Organism( average_position, average_gene_dict, average_generation, average_id, average_energy_loss, average_polygon)) self.organisms[-1].limit_position( ) # Just in case organism.set_mating(False) other_organism.set_mating(False) organism.set_time_left_before_mating( organism.get_reproduction_wait_period( )) other_organism.set_time_left_before_mating( other_organism. get_reproduction_wait_period()) for seen_organism in seen_organisms: if organism != seen_organism: organism_map_position = self.position_to_map_position( organism.get_position()) organism.make_decision([seen_organism], [ self.nutrientmap[organism_map_position[0]][ organism_map_position[1]], self.heatmap[organism_map_position[0]][ organism_map_position[1]], self.moisturemap[organism_map_position[0]][ organism_map_position[1]] ]) break # UI drawing pygame.draw.rect( screen, (UI.UI_COLOUR), (screen_dimensions_without_hud[0], 0, screen_dimensions_without_hud[0], screen_dimensions[1])) if self.target_organism: Text.draw_text( screen_dimensions_without_hud[0] + 1 * UI.PADDING, 0 + 1 * UI.PADDING, self.target_organism.get_name(), UI.HEADER_TEXT_SIZE) Text.draw_text( screen_dimensions_without_hud[0] + 1 * UI.PADDING, 8 + 2 * UI.PADDING, "Generation: " + str(self.target_organism.get_generation())) Text.draw_text( screen_dimensions_without_hud[0] + 1 * UI.PADDING, 8 + 3 * UI.PADDING, "Origin ID: " + self.target_organism.get_id(), UI.TEXT_SIZE) Text.draw_text( screen_dimensions_without_hud[0] + 1 * UI.PADDING, 8 + 4 * UI.PADDING, "Fitness: " + str(self.target_organism.get_current_fitness()) + "/" + str(self.target_organism.get_max_fitness()), UI.TEXT_SIZE) Text.draw_text( screen_dimensions_without_hud[0] + 1 * UI.PADDING, 8 + 5 * UI.PADDING, "Energy: " + str(self.target_organism.get_current_energy()) + "/" + str(self.target_organism.get_max_energy()), UI.TEXT_SIZE) if self.target_organism.get_object_detected(): self.can_see_text = "Can see: " + self.target_organism.get_object_detected( ).get_name() else: self.can_see_text = "Can see: none" Text.draw_text( screen_dimensions_without_hud[0] + 1 * UI.PADDING, 8 + 6 * UI.PADDING, self.can_see_text, UI.TEXT_SIZE) Text.draw_text( screen_dimensions_without_hud[0] + UI.PADDING, 8 + 7 * UI.PADDING, "Nodes: " + str(self.target_organism.get_point_count())) Text.draw_text( screen_dimensions_without_hud[0] + UI.PADDING, 8 + 8 * UI.PADDING, "Mood: " + self.target_organism.get_mood_name()) Text.draw_text( screen_dimensions_without_hud[0] + UI.PADDING, 8 + 9 * UI.PADDING, "Time left: " + str(self.target_organism.get_time_left()) + "/" + str(Constants.ORGANISM_LIFESPAN)) # Draw the organism's brain # Draw the input layer for n in range(len(self.target_organism.get_inputs())): pygame.draw.circle( screen, UI.NODE_DRAW_COLOUR, (screen_dimensions_without_hud[0] + UI.PADDING, 2 * n * UI.NODE_DRAW_SIZE + 186), UI.NODE_DRAW_SIZE) Text.draw_text( screen_dimensions_without_hud[0] + 6, 2 * n * UI.NODE_DRAW_SIZE + 186 - 5, str(round(self.target_organism.get_inputs()[n], 2)), UI.NODE_TEXT_SIZE, (255, 255, 255)) Text.draw_text( screen_dimensions_without_hud[0] + 20, 2 * n * UI.NODE_DRAW_SIZE + 186 - 5, self.target_organism.get_input_names()[n], UI.NODE_TEXT_SIZE, (0, 0, 0)) # Draw the hidden layer for n in range(len( self.target_organism.get_hidden_layer())): pygame.draw.circle( screen, UI.NODE_DRAW_COLOUR, (screen_dimensions_without_hud[0] + UI.PADDING + 50, 2 * n * UI.NODE_DRAW_SIZE + 186), UI.NODE_DRAW_SIZE) Text.draw_text( screen_dimensions_without_hud[0] + 50 + 6, 2 * n * UI.NODE_DRAW_SIZE + 186 - 5, str( round( self.target_organism.get_hidden_layer()[n], 2)), UI.NODE_TEXT_SIZE, (255, 255, 255)) # Draw the output layer for n in range(len(self.target_organism.get_outputs())): pygame.draw.circle( screen, UI.NODE_DRAW_COLOUR, (screen_dimensions_without_hud[0] + UI.PADDING + 100, 2 * n * UI.NODE_DRAW_SIZE + 186), UI.NODE_DRAW_SIZE) Text.draw_text( screen_dimensions_without_hud[0] + 100 + 6, 2 * n * UI.NODE_DRAW_SIZE + 186 - 5, str(round(self.target_organism.get_outputs()[n], 2)), UI.NODE_TEXT_SIZE, (255, 255, 255)) else: Text.draw_text( screen_dimensions_without_hud[0] + 1 * UI.PADDING, 0 + 1 * UI.PADDING, "Click an organism for more info...", UI.HEADER_TEXT_SIZE) Text.draw_text( screen_dimensions_without_hud[0] + UI.PADDING, screen_dimensions_without_hud[1] - 8 - 2 * UI.PADDING, "Population: " + str(len(self.organisms)) + "/" + str(Constants.POPULATION_LIMIT), UI.HEADER_TEXT_SIZE) pygame.display.flip() #Updates display clock.tick(60) pygame.quit() #Quits if all loops are exited