-
Notifications
You must be signed in to change notification settings - Fork 1
/
Brain.gd
146 lines (126 loc) · 3.27 KB
/
Brain.gd
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
extends Node2D
class_name Brain
var INPUT_SIZE:int = 15
var OUTPUT_SIZE:int = 4 #8 for veto controls, 4 for tank
var RECURRENT_SIZE:int = 15
var inputBuffer:Array = []
var outputBuffer:Array = []
var recurrentBuffer_old:Array = []
var recurrentBuffer_new:Array = []
var gates:Array = []
#var gateLogic = [
# [[0,0],[0,0]],
# [[0,0],[0,1]],
# [[0,0],[1,0]], # x > y
# [[0,0],[1,1]],
# [[0,1],[0,0]],
# [[0,1],[0,1]],
# [[0,1],[1,0]],
# [[0,1],[1,1]],
# [[1,0],[0,0]],
# [[1,0],[0,1]],
# [[1,0],[1,0]],
# [[1,0],[1,1]],
# [[1,1],[0,0]],
# [[1,1],[0,1]],
# [[1,1],[1,0]],
# [[1,1],[1,1]] ]
func gateLogic(l:int,x:float,y:float) -> float:
if l== 0:
return 0.0
elif l== 1:
return (1-x)*(1-y)
elif l== 2:
return (1-x)*y
elif l== 3:
return 1-x
elif l== 4:
return x*(1-y)
elif l== 5:
return 1-y
elif l== 6:
return 1-(1-x*(1-y))*(1-(1-x)*y)
elif l== 7:
return 1-x*y
elif l== 8:
return x*y
elif l== 9:
return (1-x*(1-y))*(1-(1-x)*y)
elif l== 10:
return y
elif l== 11:
return 1- x*(1-y)
elif l== 12:
return x
elif l== 13:
return 1-(1-x)*y
elif l== 14:
return 1-(1-x)*(1-y)
elif l== 15:
return 1.0
#begin non-boolean gates
elif l== 16:
# x > y fuzzy
if x > y:
return x-y
else:
return 0.0
else:
print("Error in MarkovBrain.gateLogic()! Logic ",l," is not defined.")
return -1.0
func get_size()->Array:
return [INPUT_SIZE, OUTPUT_SIZE, RECURRENT_SIZE]
func get_newHidden()->Array:
return recurrentBuffer_new
# Called when the node enters the scene tree for the first time.
func _ready():
for _i in range(INPUT_SIZE):
inputBuffer.append(0.5)
for _i in range(OUTPUT_SIZE):
outputBuffer.append(0.5)
for _i in range(RECURRENT_SIZE):
recurrentBuffer_old.append(0.5)
recurrentBuffer_new.append(0.5)
func make_from_genome(genome: Genome):
for _g in range(OUTPUT_SIZE + RECURRENT_SIZE):
var newGate = []
#add input wires
newGate.append(genome.get_value(0,(INPUT_SIZE + RECURRENT_SIZE)-1))
newGate.append(genome.get_value(0,(INPUT_SIZE + RECURRENT_SIZE)-1))
#add logic table
newGate.append(genome.get_value(0,(16+1)-1))
gates.append(newGate)
func update():
for i in range(OUTPUT_SIZE + RECURRENT_SIZE):
var gate = gates[i]
var input1 = inputBuffer[gate[0]] if gate[0] < INPUT_SIZE else recurrentBuffer_old[gate[0]-INPUT_SIZE]
var input2 = inputBuffer[gate[1]] if gate[1] < INPUT_SIZE else recurrentBuffer_old[gate[1]-INPUT_SIZE]
if i < OUTPUT_SIZE:
# outputBuffer[i] = gateLogic[gate[2]][input1][input2]
outputBuffer[i] = gateLogic(gate[2],input1,input2)
else:
# recurrentBuffer_new[i-OUTPUT_SIZE] = gateLogic[gate[2]][input1][input2]
recurrentBuffer_new[i-OUTPUT_SIZE] = gateLogic(gate[2],input1,input2)
transfer_recurrent()
func set_input(pos:int,val:float):
inputBuffer[pos] = val
func get_input(pos:int)->float:
return inputBuffer[pos]
func clear_input():
for i in range(INPUT_SIZE):
inputBuffer[i] = 0
func get_output(pos:int):
return outputBuffer[pos]
func clear_output():
for o in range(OUTPUT_SIZE):
outputBuffer[o] = 0
func transfer_recurrent():
recurrentBuffer_old = [] + recurrentBuffer_new #shitty vector copy
func clear_recurrent():
for r in range(RECURRENT_SIZE):
recurrentBuffer_old[r] = 0
recurrentBuffer_new[r] = 0
func reset_brain():
clear_input()
clear_output()
clear_recurrent()