-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpopulation.py
67 lines (49 loc) · 1.67 KB
/
population.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
from bird import *
import random
X = 80
class Population:
birds: list
def __init__(self, size):
self.birds = []
for i in range(size):
self.birds.append(Bird(X, 400))
def on_draw(self):
for bird in self.birds:
bird.on_draw()
def on_update(self, dt, pipes):
dead_count = 0
for bird in self.birds:
bird.on_update(dt, pipes)
if bird.is_dead:
dead_count += 1
if dead_count >= len(self.birds):
# Reset all birds
for bird in self.birds:
bird.reset()
self.natural_selection()
def pick_random(self):
max_sum = sum([b.calculate_fitness() for b in self.birds])
r = random.random() * max_sum
running_sum = 0
for b in self.birds:
running_sum += b.calculate_fitness()
if running_sum >= r:
return b
raise Exception('This shouldn\'t happen.')
def natural_selection(self):
s = sorted(self.birds, key=lambda b: b.calculate_fitness(), reverse=True)[
0:round(len(self.birds)/2)]
parent_pairs = []
new_birds = []
parent_pairs.append([s[0], s[0]])
for i in range(len(s)-1):
parent_pairs.append([
s[i],
s[i+1]
])
for i in range(len(self.birds) - len(parent_pairs)):
# Fill in the rest of the spots with randomly chosen birds
new_birds.append(self.pick_random())
for parent_pair in parent_pairs:
new_birds.append(parent_pair[0].crossover(parent_pair[1]))
self.birds = new_birds