def play_against_boring_ai(self): # if nobody survived the last generation, generate a new population if len(self.population) == 0: print('\nCreating new population') self.strict_breeding = False self.games = [] self.generation = 0 while len(self.population) < self.population_size: game = PongGame() nn_paddle = NNPaddle(PongGame.window_width - 50, PongGame.window_height / 2, game.ball, game) nn_paddle.generation = self.generation game.paddle1 = nn_paddle # ai_2 = NNPaddle(50, PongGame.window_height / 2, ball, game) self.population.append(nn_paddle) self.games.append(game) for game in self.games: game.paddle2.ball = game.ball game.speed = self.cur_speed game.start_game() print(game.paddle1) self.cur_speed = game.speed else: print('\n=== Generation', self.generation, '===') for game in self.games: game.paddle2.ball = game.ball game.paddle2.score = 0 game.paddle1.score = 0 game.paddle1.reset(PongGame.window_width - 50, PongGame.window_height / 2, game.ball) game.speed = self.cur_speed game.start_game() print(game.paddle1) self.cur_speed = game.speed
def init_breeder(self, parent=None): # if there is no parent, create a new randomly generated population if parent is None: self.create_new_population() population = [] for game in self.games: # set the game up to play using the new paddles and ball game.paddle1.ball = game.ball game.paddle2.ball = game.ball game.speed = self.cur_speed # play the game and record the game speed multiplier to use for future games game.start_game() print(game.paddle1) self.cur_speed = game.speed # append the neural net to the population population.append(game.paddle1) # sort the population best -> worst self.population = sorted(population, key=lambda x: x.fitness, reverse=True) # if there is a parent, create a generation based off the parent's genes elif parent is not None: population = parent if type(parent) is list: self.generation = population[0].generation else: self.generation = parent.generation print(population, len(population)) # go through the population and assign paddles to games, balls to paddles, etc for p in population: game = PongGame() p.game = game p.ball = game.ball game.paddle1 = p self.games.append(game) for i in range(self.population_size - 1): if type(parent) is list and len(parent) > 1: population.append( self.crossover(random.choice(parent), random.choice(parent))) else: population.append(self.crossover(parent)) self.population = population self.generation = self.population[0].generation
def crossover(self, parent1, parent2=None): # use the parent as a skeleton to create the offspring, like adam and eve or something game = PongGame() offspring = copy.deepcopy(parent1) offspring.game = game offspring.ball = game.ball game.paddle1 = offspring self.games.append(game) # if no other parent, breed with some random if parent2 is None: mate = NNPaddle(PongGame.window_width - 50, PongGame.window_height / 2, offspring.game.ball, offspring.game) offspring.parents = [parent1, mate] else: offspring.parents = [parent1, parent2] mate = parent2 offspring.fitness = 0 offspring.contacts_ball = 0 offspring.generation = self.generation # perform crossover for each layer and synapse for layer in range(len(offspring.net.synapses)): for synapse in range(len(offspring.net.synapses[layer])): # if the laws of nature say it must be so, mutate the current synapse if random.uniform(0, 1) < self.mutation_rate: offspring.net.synapses[layer][ synapse].weight = self.mutate( offspring.net.synapses[layer][synapse].weight) else: if random.uniform(0, 1) > (1 / 3): offspring.net.synapses[layer][ synapse].weight = parent1.net.synapses[layer][ synapse].weight else: offspring.net.synapses[layer][ synapse].weight = mate.net.synapses[layer][ synapse].weight # crossover the parent's colors as well offspring.colors = [ parent1.colors[0], mate.colors[1], parent1.colors[2], mate.colors[3] ] f_name = random.choice(parent1.name.split()) l_name = random.choice(mate.name.split()) offspring.name = f_name + ' ' + l_name return offspring
def create_new_population(self): print('\nCreating new population of size', self.population_size) self.generation = 0 self.train_each_other = False temp_population_size = self.population_size population = [] # create new games and neural net paddles equal to the population size for ndx in range(temp_population_size): game = PongGame() ai_1 = NNPaddle(PongGame.window_width - 50, PongGame.window_height / 2, game.ball, game) ai_1.generation = self.generation # ai_2 = NNPaddle(50, PongGame.window_height / 2, ball, game) game.paddle1 = ai_1 population.append(ai_1) # population.append(ai_2) self.games.append(game) self.population = population