def crossover(self):
     #Introduce crossover
     i = 0
     while len(self.new_generation) < self.number_of_agents:
         
         new_agent = NeuralNetwork()
         
         #Copy half of all weights from parent i and parent i+1
         new_agent.weights_left = np.concatenate((self.list_of_neural_nets[i].weights_left[:int(len(self.list_of_neural_nets[i].weights_left)/2)], \
                                                  self.list_of_neural_nets[i+1].weights_left[int(len(self.list_of_neural_nets[i+1].weights_left)/2):]))
     
         new_agent.weights_down = np.concatenate((self.list_of_neural_nets[i].weights_down[:int(len(self.list_of_neural_nets[i].weights_down)/2)], \
                                                  self.list_of_neural_nets[i+1].weights_down[int(len(self.list_of_neural_nets[i+1].weights_down)/2):]))
     
         new_agent.weights_right = np.concatenate((self.list_of_neural_nets[i].weights_right[:int(len(self.list_of_neural_nets[i].weights_right)/2)], \
                                                   self.list_of_neural_nets[i+1].weights_right[int(len(self.list_of_neural_nets[i+1].weights_right)/2):]))
     
         new_agent.weights_rotate = np.concatenate((self.list_of_neural_nets[i].weights_rotate[:int(len(self.list_of_neural_nets[i].weights_rotate)/2)], \
                                                    self.list_of_neural_nets[i+1].weights_rotate[int(len(self.list_of_neural_nets[i+1].weights_rotate)/2):]))
         
         self.new_generation.append(new_agent)
         
         i += 1
     
     print(f"Number of agents for next generation: {len(self.list_of_neural_nets)}")
 i = 0
 while len(new_generation) < number_of_agents:
     
     new_agent = NeuralNetwork()
     
     #Copy half of all weights from parent i and parent i+1
     new_agent.weights_left = np.concatenate((list_of_neural_nets[i].weights_left[:int(len(list_of_neural_nets[i].weights_left)/2)], \
                                              list_of_neural_nets[i+1].weights_left[int(len(list_of_neural_nets[i+1].weights_left)/2):]))
 
     new_agent.weights_down = np.concatenate((list_of_neural_nets[i].weights_down[:int(len(list_of_neural_nets[i].weights_down)/2)], \
                                              list_of_neural_nets[i+1].weights_down[int(len(list_of_neural_nets[i+1].weights_down)/2):]))
 
     new_agent.weights_right = np.concatenate((list_of_neural_nets[i].weights_right[:int(len(list_of_neural_nets[i].weights_right)/2)], \
                                              list_of_neural_nets[i+1].weights_right[int(len(list_of_neural_nets[i+1].weights_right)/2):]))
 
     new_agent.weights_rotate = np.concatenate((list_of_neural_nets[i].weights_rotate[:int(len(list_of_neural_nets[i].weights_rotate)/2)], \
                                              list_of_neural_nets[i+1].weights_rotate[int(len(list_of_neural_nets[i+1].weights_rotate)/2):]))
     
     new_generation.append(new_agent)
     
     i += 1
     
     
     
 # for i, agent in enumerate(list_of_neural_nets):
 #     print(list_of_neural_nets[0].weights_left - list_of_neural_nets[1].weights_left)
 #     print(list_of_neural_nets[1].weights_left)
 #     agent[i].weights_left
     
     
     
 print(f"Number of agents for next generation: {len(list_of_neural_nets)}")