-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpopulation.py
132 lines (99 loc) · 3.31 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
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 config
import player
import math
import species
import operator
class Population:
def __init__(self, size):
self.players = []
self.generation = 1
self.species = []
self.size = size
for i in range(0, self.size):
self.players.append(player.Player())
def update_live_players(self):
for p in self.players:
if p.alive:
p.look()
p.think()
p.draw(config.window)
p.update(config.ground)
def natural_selection(self):
print('SPECIATE')
self.speciate()
print('CALCULATE FITNESS')
self.calculate_fitness()
print('KILL EXTINCT')
self.kill_extinct_species()
print('KILL STALE')
self.kill_stale_species()
print('SORT BY FITNESS')
self.sort_species_by_fitness()
print('CHILDREN FOR NEXT GEN')
self.next_gen()
def speciate(self):
for s in self.species:
s.players = []
for p in self.players:
add_to_species = False
for s in self.species:
if s.similarity(p.brain):
s.add_to_species(p)
add_to_species = True
break
if not add_to_species:
self.species.append(species.Species(p))
def calculate_fitness(self):
for p in self.players:
p.calculate_fitness()
for s in self.species:
s.calculate_average_fitness()
def kill_extinct_species(self):
species_bin = []
for s in self.species:
if len(s.players) == 0:
species_bin.append(s)
for s in species_bin:
self.species.remove(s)
def kill_stale_species(self):
player_bin = []
species_bin = []
for s in self.species:
if s.staleness >= 8:
if len(self.species) > len(species_bin) + 1:
species_bin.append(s)
for p in s.players:
player_bin.append(p)
else:
s.staleness = 0
for p in player_bin:
self.players.remove(p)
for s in species_bin:
self.species.remove(s)
def sort_species_by_fitness(self):
for s in self.species:
s.sort_players_by_fitness()
self.species.sort(key=operator.attrgetter('benchmark_fitness'), reverse=True)
def next_gen(self):
children = []
# Clone of champion is added to each species
for s in self.species:
children.append(s.champion.clone())
# Fill open player slots with children
children_per_species = math.floor((self.size - len(self.species)) / len(self.species))
for s in self.species:
for i in range(0, children_per_species):
children.append(s.offspring())
while len(children) < self.size:
children.append(self.species[0].offspring())
self.players = []
for child in children:
self.players.append(child)
self.generation += 1
# Return true if all players are dead
def extinct(self):
extinct = True
for p in self.players:
if p.alive:
extinct = False
return extinct