-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathPopulation.pde
160 lines (147 loc) · 5.13 KB
/
Population.pde
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
class Population {
ArrayList<Player> originalPlayers = new ArrayList<Player>();
int player1;
int player2;
ArrayList<ConnectionHistory> innovationHistory = new ArrayList<ConnectionHistory>();
ArrayList<Player> genPlayers = new ArrayList<Player>();
Board board;
int totalPlayers;
Player bestPlayer;//the best ever player
int currentPlayer = 0; //current player
int currentPlaying = 0; //Who the current player is playing against
int generation = 0;
boolean isPlayer1 = true;
ArrayList<Integer> playersPlayed = new ArrayList<Integer>();
Population(int size) {
totalPlayers = size;
for (int i =0; i<size; i++) {
originalPlayers.add(new Player());
originalPlayers.get(i).brain.generateNetwork();
originalPlayers.get(i).brain.mutate(innovationHistory);
}
getNextPlayer();
board = new Board(originalPlayers.get(currentPlayer), originalPlayers.get(currentPlaying));
}
void showGo() {
board.showGo();
}
void performGo() {
if (board.winner == 0) board.haveGo(); //If there isn't a winner have a go
else { //Else someone has won
if (!(currentPlayer == originalPlayers.size() - 2 && playersPlayed.size() == 50)) { //If this generation isn't over
if (playersPlayed.size() < 50) {
getNextPlayer();
} else {
playersPlayed.clear();
currentPlayer++;
getNextPlayer();
}
board = null;
if(playersPlayed.size() > 25) board = new Board(originalPlayers.get(currentPlayer), originalPlayers.get(currentPlaying));
else board = new Board(originalPlayers.get(currentPlaying), originalPlayers.get(currentPlayer));
} else {//Generation is over
generation++;
for (int i = 0; i < originalPlayers.size(); i++) {
originalPlayers.get(i).calculateFitness();
genPlayers.add(originalPlayers.get(i));
}
originalPlayers.clear();
naturalSelection();
currentPlaying = 0;
currentPlayer = 0;
getNextPlayer();
}
}
}
void naturalSelection() {
genPlayers = sortPlayers();
cullPlayers();
originalPlayers.add(genPlayers.get(genPlayers.size() - 1).clone());
println("Generation : " + generation);
println("Wins : " + genPlayers.get(genPlayers.size() - 1).wins);
println("Draws : " + genPlayers.get(genPlayers.size() - 1).draws);
println("Losses : " + genPlayers.get(genPlayers.size() - 1).losses);
println("Fitness : " + genPlayers.get(genPlayers.size() - 1).fitness);
println();
while (originalPlayers.size() < totalPlayers) {
originalPlayers.add(giveMeBaby());
}
for (int i = 0; i< originalPlayers.size(); i++) {//generate networks for each of the children
originalPlayers.get(i).brain.generateNetwork();
}
}
Player giveMeBaby() {
Player baby;
if (random(1) < 0.10) {//10% of the time there is no crossover and the child is simply a clone of a random(ish) player
baby = selectPlayer().clone();
} else {//90% of the time do crossover
//get 2 random(ish) parents
Player parent1 = selectPlayer();
Player parent2 = selectPlayer();
//the crossover function expects the highest fitness parent to be the object and the lowest as the argument
if (parent1.fitness < parent2.fitness) {
baby = parent2.crossover(parent1);
} else {
baby = parent1.crossover(parent2);
}
}
baby.brain.mutate(innovationHistory);//mutate that baby brain
return baby;
}
Player selectPlayer() {
float fitnessSum = 0;
for (int i =0; i<genPlayers.size(); i++) {
fitnessSum += genPlayers.get(i).fitness;
}
float rand = random(fitnessSum);
float runningSum = 0;
for (int i = 0; i<genPlayers.size(); i++) {
runningSum += genPlayers.get(i).fitness;
if (runningSum > rand) {
return genPlayers.get(i);
}
}
//unreachable code to make the parser happy
return genPlayers.get(0);
}
//-
void cullPlayers() {
int total = genPlayers.size() / 2;
for (int i = 0; i < total; i++) {
genPlayers.remove(0);
}
}
ArrayList<Player> sortPlayers() {
ArrayList<Player> tmpPlayers = new ArrayList<Player>();
int size = genPlayers.size();
for (int i = 0; i < size; i++) {
float lowestFitness = genPlayers.get(0).fitness;
int lowestFitnessId = 0;
for (int j = 0; j < genPlayers.size(); j++) {
if (lowestFitness > genPlayers.get(j).fitness) {
lowestFitness = genPlayers.get(j).fitness;
lowestFitnessId = j;
}
}
tmpPlayers.add(genPlayers.get(lowestFitnessId));
genPlayers.remove(lowestFitnessId);
}
return tmpPlayers;
}
void getNextPlayer() {
boolean playerFound = false;
while (!playerFound) {
boolean duplicate = false;
currentPlaying = int(random(originalPlayers.size() - 1));
if(currentPlaying != currentPlayer) {
if(playersPlayed.size() > 0){
for(int played : playersPlayed){
if(played == currentPlaying) duplicate = true;
}
}
if(!duplicate) playerFound = true;
}
}
playersPlayed.add(currentPlaying);
}
}