mirror of https://github.com/dirtbags/tanks.git
Start at Golang evolver, someone else can port the couple functions to do the GA from ML
This commit is contained in:
parent
0b701722fe
commit
975c4111e9
|
@ -0,0 +1,189 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"time"
|
||||
"strings"
|
||||
"io/ioutil"
|
||||
)
|
||||
|
||||
type sensor struct {
|
||||
srange int
|
||||
angle int
|
||||
width int
|
||||
turret bool
|
||||
}
|
||||
|
||||
type Tank struct {
|
||||
color string
|
||||
sensors [10]sensor
|
||||
program []string
|
||||
}
|
||||
|
||||
var symbols []string = []string{
|
||||
"~",
|
||||
"!",
|
||||
"+",
|
||||
"-",
|
||||
"*",
|
||||
"/",
|
||||
"%",
|
||||
"&",
|
||||
"|",
|
||||
"^",
|
||||
"<<",
|
||||
">>",
|
||||
">",
|
||||
">=",
|
||||
"<",
|
||||
"<=",
|
||||
"=",
|
||||
"<>",
|
||||
"abs",
|
||||
"dup",
|
||||
"pop",
|
||||
"exch",
|
||||
"if",
|
||||
"ifelse",
|
||||
"mset",
|
||||
"mget",
|
||||
"{",
|
||||
"}",
|
||||
"fire-ready?",
|
||||
"fire!",
|
||||
"set-speed!",
|
||||
"get-turret",
|
||||
"set-turret!",
|
||||
"sensor?",
|
||||
"set-led!",
|
||||
"random",
|
||||
}
|
||||
|
||||
func make_nucleotide() int {
|
||||
switch rand.Intn(3) {
|
||||
case 0:
|
||||
return rand.Intn(len(symbols))
|
||||
case 1:
|
||||
return len(symbols) + rand.Intn(720)
|
||||
case 2:
|
||||
return len(symbols) + 720 + rand.Intn(100)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func make_dna(size int) []int {
|
||||
ret := make([]int, size)
|
||||
for i := 0; i < size; i += 1 {
|
||||
ret[i] = make_nucleotide()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func color_of_dna(dna []int) (string, []int) {
|
||||
if len(dna) >= 3 {
|
||||
r := dna[0] % 256
|
||||
g := dna[1] % 256
|
||||
b := dna[2] % 256
|
||||
color := fmt.Sprintf("%02x%02x%02x", r, g, b)
|
||||
return color, dna[3:]
|
||||
} else {
|
||||
return "cccccc", dna
|
||||
}
|
||||
}
|
||||
|
||||
func sensor_of_dna(dna []int) (sensor, []int) {
|
||||
if len(dna) >= 4 {
|
||||
return sensor{dna[0], dna[1], dna[2], dna[3] % 2 == 0}, dna[4:]
|
||||
} else {
|
||||
return sensor{0, 0, 0, false}, dna
|
||||
}
|
||||
}
|
||||
|
||||
func program_of_dna(dna []int) []string {
|
||||
ret := make([]string, 0, len(dna))
|
||||
|
||||
stacks := []int{}
|
||||
for i := 0; i < len(dna); i += 1 {
|
||||
// If we are in a stack, decrement the size
|
||||
if len(stacks) > 0 {
|
||||
stacks[0] -= 1
|
||||
// Are we at the end of the stack? Output the symbol and pop the stack off.
|
||||
if stacks[0] <= 0 {
|
||||
ret = append(ret, "}")
|
||||
stacks = stacks[1:]
|
||||
}
|
||||
}
|
||||
|
||||
// Consider the next nucleotide
|
||||
n := dna[i]
|
||||
|
||||
// Symbol?
|
||||
if n < len(symbols) {
|
||||
ret = append(ret, symbols[n])
|
||||
continue
|
||||
}
|
||||
n -= len(symbols)
|
||||
|
||||
// Number?
|
||||
if n < 720 {
|
||||
ret = append(ret, strconv.Itoa(n - 360))
|
||||
continue
|
||||
}
|
||||
n -= 720
|
||||
|
||||
// Stack.
|
||||
ret = append(ret, "{")
|
||||
stacks = append(stacks, (n + 1) % (len(dna) - i))
|
||||
}
|
||||
|
||||
for len(stacks) > 0 {
|
||||
ret = append(ret, "}")
|
||||
stacks = stacks[1:]
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func tank_of_dna(dna []int) Tank {
|
||||
ret := Tank{}
|
||||
ret.color, dna = color_of_dna(dna)
|
||||
for i := 0; i < len(ret.sensors); i += 1 {
|
||||
ret.sensors[i], dna = sensor_of_dna(dna)
|
||||
}
|
||||
ret.program = program_of_dna(dna)
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
func twrite(num int, fn string, contents string) {
|
||||
path := fmt.Sprintf("tank.%d/%s", num, fn)
|
||||
ioutil.WriteFile(path, []byte(contents), 0644)
|
||||
}
|
||||
|
||||
func (t Tank) Write(num int, dir string) {
|
||||
twrite(num, "color", t.color)
|
||||
for i := 0; i < len(t.sensors); i += 1 {
|
||||
turret := 0
|
||||
if t.sensors[i].turret {
|
||||
turret = 1
|
||||
}
|
||||
twrite(
|
||||
num,
|
||||
fmt.Sprintf("sensor%d", i),
|
||||
fmt.Sprintf("%d %d %d %d", t.sensors[i].srange, t.sensors[i].angle, t.sensors[i].width, turret),
|
||||
)
|
||||
}
|
||||
twrite(num, "program", strings.Join(t.program, " "))
|
||||
}
|
||||
|
||||
func init() {
|
||||
rand.Seed(time.Now().UTC().UnixNano())
|
||||
}
|
||||
|
||||
func main() {
|
||||
d := make_dna(20)
|
||||
p := program_of_dna(d)
|
||||
fmt.Println(p)
|
||||
}
|
Loading…
Reference in New Issue