diff --git a/car.py b/car.py index 4cf6a2e..a159ea8 100644 --- a/car.py +++ b/car.py @@ -62,6 +62,7 @@ class Car(pygame.sprite.Sprite): self.run = True self.distance_run = 0 self.creation_dt = datetime.datetime.now() + self.run_time = 0 def reset_car_pos(self): self.rect.center = ( @@ -109,10 +110,9 @@ class Car(pygame.sprite.Sprite): -self.speed * vec[1] / 2 + old_center[1], ) self.update_sensors() - self.distance_run += int(distance(old_center, self.rect.center)) - self.brain.fitness = int( - math.sqrt(self.distance_run) - ) # - 2 # penalize jittering + if self.run: + self.distance_run += int(distance(old_center, self.rect.center)) + self.brain.fitness = math.sqrt(self.distance_run) def probe_lines_proximity(self, lines): # print(self.center_sensor, lines[0]) @@ -150,16 +150,16 @@ class Car(pygame.sprite.Sprite): self.rect = self.image.get_rect() self.rect.center = old_center self.update_position() - run_time = (datetime.datetime.now() - self.creation_dt).seconds - if run_time > MAX_RUN_TIME: + self.run_time = (datetime.datetime.now() - self.creation_dt).seconds + if self.run_time > MAX_RUN_TIME: print("RUNTIME EXCEEDED") if ( self.speed < 0.01 or self.brain.fitness > CAR_MAX_FITNESS - or run_time > MAX_RUN_TIME + or self.run_time > MAX_RUN_TIME ): self.run = False - print(f"Car {id(self)} crashed") + # print(f"Car {id(self)} crashed") # print( # 'id', id(self), # 'Speed', self.speed, diff --git a/genetics.py b/genetics.py index 3cfdcea..593066c 100644 --- a/genetics.py +++ b/genetics.py @@ -34,7 +34,7 @@ def genetic_selection(brains): # proportionnally to its relative fitness wheel = [] for b in brains: - wheel += [b] * b.fitness + wheel += [b] * int(b.fitness) tot_fitness = len(wheel) diff --git a/main.py b/main.py index 3f2cfd4..ff4752d 100755 --- a/main.py +++ b/main.py @@ -13,11 +13,13 @@ from params import CELL_COLOR, GX, GY, screen # https://medium.com/intel-student-ambassadors/demystifying-genetic-algorithms-to-enhance-neural-networks-cde902384b6e clock = pygame.time.Clock() font = pygame.font.SysFont("hack", 24) - +small_font = pygame.font.SysFont("hack", 12) map_lines = map1 - - all_cars = pygame.sprite.Group() +loop = 0 +max_fitness = 0 +avg_fitness = 0 + for x in range(100): car = Car() @@ -25,6 +27,8 @@ for x in range(100): def run_round(all_cars): + global max_fitness + global avg_fitness running_cars = True while running_cars: running_cars = False @@ -40,8 +44,12 @@ def run_round(all_cars): for line in map_lines: pygame.draw.line(screen, (255, 255, 255), line[0], line[1]) - text = font.render(f"Generation {loop}", True, (128, 128, 128)) + text = font.render(f"Gen # : {loop}", True, (128, 128, 128)) + mft = small_font.render(f"max fitness : {max_fitness}", True, (128, 128, 128)) + aft = small_font.render(f"avg fitness : {avg_fitness}", True, (128, 128, 128)) screen.blit(text, (GX - 50 - text.get_width(), text.get_height() // 2)) + screen.blit(mft, (GX - 50 - text.get_width(), text.get_height() // 2 + 30)) + screen.blit(aft, (GX - 50 - text.get_width(), text.get_height() // 2 + 50)) pygame.display.flip() clock.tick(48) @@ -51,6 +59,9 @@ def run_round(all_cars): print("Collecting brains") brains = [c.brain for c in all_cars] + + max_fitness = round(max([b.fitness for b in brains]), 2) + avg_fitness = round(sum([b.fitness for b in brains]) / len(brains), 2) print(f"Max fitness = {max([b.fitness for b in brains])}") print(f"Avg fitness = {sum([b.fitness for b in brains])/len(brains)}") print("selecting") @@ -68,7 +79,6 @@ def run_round(all_cars): pygame.display.flip() -loop = 0 while True: loop += 1 run_round(all_cars) diff --git a/params.py b/params.py index 5e66a82..36f76be 100644 --- a/params.py +++ b/params.py @@ -10,7 +10,7 @@ CAR_SIZE = 20 CAR_MAX_SPEED = 100 CAR_MAX_FITNESS = 100 CAR_STEERING_FACTOR = 10 -MAX_RUN_TIME = 60 +MAX_RUN_TIME = 120 VISION_LENGTH = 100 VISION_SPAN = 35 # degrees THROTTLE_POWER = 3