-
Notifications
You must be signed in to change notification settings - Fork 0
/
genetic.py
128 lines (97 loc) · 4.24 KB
/
genetic.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
122
123
124
125
126
from play import play_game
import time
import random
import copy
import sys
def cutoff_depth(d):
return lambda game, state, depth: depth > d
def fitness(turns):
return 30-turns
def create_starting_population(elements = 10):
population = []
for i in range(elements):
population.append([random.uniform(0, 2), random.uniform(0, 2), random.uniform(0, 10), random.uniform(0, 2), random.uniform(0, 3)])
return population
def cross_chromosome(chromosome1, chromosome2):
alpha0, beta0, gamma0, theta0, epsilon0 = chromosome1
alpha1, beta1, gamma1, theta1, epsilon1 = chromosome2
new_chromosome1 = [alpha0, beta1, gamma0, theta1, epsilon0]
new_chromosome2 = [alpha1, beta0, gamma1, theta0, epsilon1]
return new_chromosome1, new_chromosome2
def mate(elements):
random1 = copy.deepcopy(random.choice(elements))
random2 = copy.deepcopy(random.choice(elements))
alpha0, beta0, gamma0, theta0, epsilon0 = random1
alpha1, beta1, gamma1, theta1, epsilon1 = random2
new_chromosome = [(alpha0+alpha1)/2, (beta0+beta1)/2, (gamma0+gamma1)/2, (theta0+theta1)/2, (epsilon0+epsilon1)/2]
return new_chromosome
def create_random_chromosome():
return [random.uniform(0, 5), random.uniform(0, 5), random.uniform(0, 5), random.uniform(0, 5), random.uniform(0, 5)]
def mutate(population, mutation_rate=0.6):
print(population)
for i in range(1, len(population)):
if random.random() < mutation_rate:
alpha, beta, gamma, theta, epsilon = population[i]
alpha += random.uniform(-1, 1)
beta += random.uniform(-1, 1)
gamma += random.uniform(-1, 1)
theta += random.uniform(-1, 1)
epsilon += random.uniform(-1, 1)
population[i] = [alpha, beta, gamma, theta, epsilon]
return population
def create_starting_from_params(alpha, beta, gamma, theta, epsilon, elements=10):
population = []
for i in range(elements):
population.append([alpha+random.uniform(-1,1), beta+random.uniform(-1,1), gamma+random.uniform(-1,1), theta+random.uniform(-1,1), epsilon+random.uniform(-1,1)])
return population
iterations = 50
elements = 10
max_moves = 30
cod = cutoff_depth(2)
population = create_starting_population(elements)
for iteration in range(iterations):
results = []
for pop in population:
print(pop)
alpha0, beta0, gamma0, theta0, epsilon0 = pop
result, turns = play_game(alpha0, beta0, gamma0, theta0, epsilon0, cod, max_moves, name="Player", team=sys.argv[1], server_ip="127.0.0.1", timeout=60)
#If result = 0, white wins
#If result = 1, black wins
#If result = 2, draw
#If result = 3, max moves reached
if result == 0:
results.append([pop, fitness(turns)])
else:
results.append([pop, -1])
time.sleep(15)
results = sorted(results, key=lambda x: x[1], reverse=True)
print("Best fitness: ", results[0][1])
print("Best parameters: ", results[0][0])
with open("results.txt", "a") as f:
f.write("Generation: " + str(iteration) + "\n")
f.write("Best fitness: " + str(results[0][1]) + "\n")
f.write("Best parameters: " + str(results[0][0]) + "\n\n")
#I copy the first element of the population
new_population = []
new_population.append(copy.deepcopy(results[0][0]))
#I cross the first element with the second and the third
e1, e2 = cross_chromosome(results[0][0], results[1][0])
new_population.append(e1)
new_population.append(e2)
e1, e2 = cross_chromosome(results[0][0], results[2][0])
new_population.append(e1)
new_population.append(e2)
#I mate from the top 5 elements creating the remaining-3 elements
top_five = copy.deepcopy(results[:5])
random.shuffle(top_five)
top_five = [x[0] for x in top_five]
new_population.append(mate(top_five))
new_population.append(mate(top_five))
new_population.append(mate(top_five))
#I add three random elements
new_population.append(create_random_chromosome())
new_population.append(create_random_chromosome())
#I mutate everything except the first element
new_population = mutate(new_population)
#I update the population
population = copy.deepcopy(new_population)