-
Notifications
You must be signed in to change notification settings - Fork 1
/
eval_genomes.py
121 lines (98 loc) · 3.59 KB
/
eval_genomes.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import pygame, random, os, sys, neat
from classes.background import Background
from classes.bird import Bird
from classes.pipe import Pipe
pygame.init()
pygame.mixer.init()
SCREEN_WIDTH, SCREEN_HEIGHT = 500, 768
SCREEN = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
FONT = pygame.font.Font('./assets/flappy.ttf', 72)
pygame.display.set_caption("NEAT - Flappy Bird")
flap_sound = pygame.mixer.Sound("./assets/bird/wing.mp3")
point_sound = pygame.mixer.Sound("./assets/point.mp3")
def display_score(score):
score_img = FONT.render("{}".format(score), True, (255, 255, 255))
score_rect = score_img.get_rect()
score_rect.center = (SCREEN_WIDTH // 2, 100)
SCREEN.blit(score_img, score_rect)
def remove_bird(i, genomes, nets, score):
genomes[i].fitness += score
Bird.birds.pop(i)
genomes.pop(i)
nets.pop(i)
def eval_genomes(genomes, config):
run = True
clock = pygame.time.Clock()
# Initialize a background
bg = Background(SCREEN_WIDTH, SCREEN_HEIGHT)
score = 0
# Setup genomes
ge = []
nets = []
for genome_id, genome in genomes:
Bird.birds.append(Bird(SCREEN_WIDTH // 2, SCREEN_HEIGHT // 2, Bird.COLORS[genome_id % 6]))
ge.append(genome)
nets.append(neat.nn.FeedForwardNetwork.create(genome, config))
genome.fitness = 0
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
pygame.quit()
if len(Bird.birds) == 0:
break
dt = 1 / 60
SCREEN.fill((255, 255, 255))
if len(Pipe.pipes) == 0 or Pipe.pipes[-1].right_x() < SCREEN_WIDTH - 300:
bottom_y = random.randint(300, SCREEN_HEIGHT - 200)
top_y = random.randint(100, bottom_y - 200)
pipe = Pipe(SCREEN_WIDTH, bottom_y, top_y)
for i, bird in enumerate(Bird.birds):
for pipe in Pipe.pipes:
if pipe.right_x() >= SCREEN_WIDTH // 2:
closest_pipe = pipe
break
output = nets[i].activate((bird.rect.y, abs(closest_pipe.top_pipe_y() - bird.rect.y), abs(closest_pipe.bottom_pipe_y() - bird.rect.y)))
if output[0] > 0.5:
bird.jump()
# Update and draw the background
bg.update(dt)
bg.draw(SCREEN)
# Update and draw the birds
for i, bird in enumerate(Bird.birds):
bird.update(dt)
# Collisions
for pipe in Pipe.pipes:
if pipe.collide(bird):
remove_bird(i, ge, nets, score)
if bird.rect.bottom < 0 or bird.rect.top > SCREEN_HEIGHT:
remove_bird(i, ge, nets, score)
bird.draw(SCREEN)
for pipe in Pipe.pipes:
pipe.update(dt)
pipe.draw(SCREEN)
if pipe.right_x() < SCREEN_WIDTH // 2 and not pipe.scored:
score += 1
pipe.scored = True
point_sound.play()
display_score(score)
pygame.display.update()
clock.tick(60)
Pipe.pipes = []
def run(config_path):
config = neat.config.Config(
neat.DefaultGenome,
neat.DefaultReproduction,
neat.DefaultSpeciesSet,
neat.DefaultStagnation,
config_path
)
pop = neat.Population(config)
pop.run(eval_genomes, 50)
if __name__ == "__main__":
if getattr(sys, 'frozen', False):
local_dir = os.path.dirname(sys.executable)
elif __file__:
local_dir = os.path.dirname(__file__)
config_path = os.path.join(local_dir, 'config.txt')
run(config_path)