forked from Ramblurr/scriptbots
-
Notifications
You must be signed in to change notification settings - Fork 44
/
AssemblyBrain.cpp
109 lines (93 loc) · 2.68 KB
/
AssemblyBrain.cpp
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
#include "AssemblyBrain.h"
#include <stdio.h>
using namespace std;
AssemblyBrain::AssemblyBrain()
{
//constructor
w.resize(BRAINSIZE, 0);
for (int i=0;i<BRAINSIZE;i++) {
w[i] = randf(-3,3);
if(randf(0,1)<0.1) w[i] = randf(0,0.5);
if(randf(0,1)<0.1) w[i] = randf(0.8,1);
}
//other inits
init();
}
void AssemblyBrain::init()
{
}
AssemblyBrain::AssemblyBrain(const AssemblyBrain& other)
{
w = other.w;
}
AssemblyBrain& AssemblyBrain::operator=(const AssemblyBrain& other)
{
if( this != &other ) {
w = other.w;
}
return *this;
}
void AssemblyBrain::tick(vector< float >& in, vector< float >& out)
{
//do a single tick of the brain
//take first few boxes and set their out to in[].
for (int i=0;i<INPUTSIZE;i++) {
w[i]= in[i];
}
//TICK!
for (int i=INPUTSIZE;i<BRAINSIZE-OUTPUTSIZE;i++) {
float v = w[i];
//this is an operand
if(v>=2 && v<3){
float v1 = w[i+1];
float v2 = w[i+2];
float v3 = w[i+3];
int d1 = (int)BRAINSIZE*(fabs(v1)-((int)fabs(v1)));
int d2 = (int)BRAINSIZE*(fabs(v2)-((int)fabs(v2)));
int d3 = (int)BRAINSIZE*(fabs(v3)-((int)fabs(v3)));
// printf("%f d1=%d d2=%d d3=%d\n", v, d1, d2, d3);
if(v<2.1) { w[d3] = w[d1] + w[d2]; continue;}
if(v<2.2) { w[d3] = w[d1] - w[d2]; continue;}
if(v<2.3) { w[d3] = w[d1] * w[d2]; continue;}
if(v<2.4) { if(w[d3]>0) w[d1] = 0; continue;}
if(v<2.5) { if(w[d3]>0) w[d1] = -w[d1]; continue;}
if(v<2.7) { if(w[d3]>0) w[d1] += v2; continue;}
if(v<3) { if(w[d3]>0) w[d1] = w[d2]; continue;}
}
}
//cap all to -10,10
for(int i=INPUTSIZE;i<BRAINSIZE-OUTPUTSIZE;i++){
float v = w[i];
if(v>10)w[i]=10;
if(v<-10)w[i]=-10;
}
//finally set out[] to the last few boxes output
for (int i=0;i<OUTPUTSIZE;i++) {
float v =w[BRAINSIZE-1-i];
if(v>1)v=1;
if(v<0)v=0;
out[i]= v;
}
}
void AssemblyBrain::mutate(float MR, float MR2)
{
for (int j=0;j<BRAINSIZE;j++) {
if(randf(0,1)<MR) {
w[j] = randf(-3,3);
}
}
}
AssemblyBrain AssemblyBrain::crossover(const AssemblyBrain& other)
{
//this could be made faster by returning a pointer
//instead of returning by value
AssemblyBrain newbrain(*this);
for (int i=0;i<newbrain.w.size(); i++) {
if(randf(0,1)<0.5){
newbrain.w[i] = this->w[i];
} else {
newbrain.w[i] = other.w[i];
}
}
return newbrain;
}