-
Notifications
You must be signed in to change notification settings - Fork 2
/
evolve.ml
167 lines (154 loc) · 3.36 KB
/
evolve.ml
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
161
162
163
164
165
166
167
type sensor = (int * int * int * bool)
type tank = (
string
* sensor
* sensor
* sensor
* sensor
* sensor
* sensor
* sensor
* sensor
* sensor
* sensor
* string list
)
let symbols = [
"~";
"!";
"+";
"-";
"*";
"/";
"%";
"&";
"|";
"^";
"<<";
">>";
">";
">=";
"<";
"<=";
"=";
"<>";
"abs";
"dup";
"pop";
"exch";
"if";
"ifelse";
"mset";
"mget";
"{";
"}";
"fire-ready?";
"fire!";
"set-speed!";
"get-turret";
"set-turret!";
"sensor?";
"set-led!";
"random";
]
let make_nucleotide () =
Random.int ((List.length symbols) + 360 + 360)
let rec make_dna = function
| 0 ->
[]
| n ->
(make_nucleotide ()) :: (make_dna (n - 1))
let rec program_of_dna = function
| [] ->
[]
| i :: tl ->
let s =
try
List.nth symbols i
with
| Failure _
| Invalid_argument _ ->
string_of_int (i - (List.length symbols) - 360)
in
s :: (program_of_dna tl)
let tank_of_dna d =
let color_of_dna = function
| r :: g :: b :: tl ->
(tl, (Format.sprintf "%02x%02x%02x"
((abs r) mod 256)
((abs g) mod 256)
((abs b) mod 256)))
| tl ->
(tl, "cccccc")
in
let sensor_of_dna = function
| a :: b :: c :: d :: tl ->
(tl, (a, b, c, (d != 0)))
| tl ->
(tl, (0, 0, 0, false))
in
let d, color = color_of_dna d in
let d, s0 = sensor_of_dna d in
let d, s1 = sensor_of_dna d in
let d, s2 = sensor_of_dna d in
let d, s3 = sensor_of_dna d in
let d, s4 = sensor_of_dna d in
let d, s5 = sensor_of_dna d in
let d, s6 = sensor_of_dna d in
let d, s7 = sensor_of_dna d in
let d, s8 = sensor_of_dna d in
let d, s9 = sensor_of_dna d in
let p = program_of_dna d in
(color, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, p)
let print_tank t =
let print_sensor (a, b, c, d) =
Format.printf "Sensor: %d %d %d %d\n" a b c (if d then 1 else 0)
in
match t with
| (color, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, p) ->
Format.printf "Color: #%s\n" color;
print_sensor s0;
print_sensor s1;
print_sensor s2;
print_sensor s3;
print_sensor s4;
print_sensor s5;
print_sensor s6;
print_sensor s7;
print_sensor s8;
print_sensor s9;
print_endline (String.concat " " p)
let write_tank i t =
let fnprint fn str =
let filename = Format.sprintf "tank.%d/%s" i fn in
let chan = open_out filename in
output_string chan str;
close_out chan
in
let print_sensor n (a, b, c, d) =
fnprint
(Format.sprintf "sensor%d" n)
(Format.sprintf "Sensor: %d %d %d %d\n" a b c (if d then 1 else 0))
in
match t with
| (color, s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, p) ->
fnprint "color" color;
print_sensor 0 s0;
print_sensor 1 s1;
print_sensor 2 s2;
print_sensor 3 s3;
print_sensor 4 s4;
print_sensor 5 s5;
print_sensor 6 s6;
print_sensor 7 s7;
print_sensor 8 s8;
print_sensor 9 s9;
fnprint "program" (String.concat " " p)
let _ = Random.self_init ()
let _ =
let dnas =
let t = Array.make 20 500 in
Array.map make_dna t
in
let tanks = Array.map tank_of_dna dnas in
Array.mapi write_tank tanks