2019-08-03 02:00:33 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"git.openprivacy.ca/sarah/microworlds/actors"
|
|
|
|
"git.openprivacy.ca/sarah/microworlds/core"
|
|
|
|
"git.openprivacy.ca/sarah/microworlds/graphics"
|
|
|
|
"github.com/veandco/go-sdl2/sdl"
|
|
|
|
"log"
|
|
|
|
"math/rand"
|
|
|
|
"os"
|
|
|
|
"runtime/pprof"
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
|
|
|
|
|
|
|
|
var model = flag.String("model", "slime", "slimemold|swarm|woodchips")
|
|
|
|
|
|
|
|
var width = flag.Int("width", 300, "width of environment")
|
|
|
|
var height = flag.Int("height", 300, "height of environment")
|
2019-08-10 02:47:26 +00:00
|
|
|
var pxsize = flag.Int("pxsize", 1, "pixels per tile edge")
|
2019-08-03 02:00:33 +00:00
|
|
|
var numTurtles = flag.Int("numTurtles", 5000, "number of turtles")
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
|
|
|
|
// We don't need real randomness
|
|
|
|
rand.Seed(time.Now().Unix())
|
|
|
|
|
|
|
|
flag.Parse()
|
|
|
|
if *cpuprofile != "" {
|
|
|
|
f, err := os.Create(*cpuprofile)
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
pprof.StartCPUProfile(f)
|
|
|
|
defer pprof.StopCPUProfile()
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
defer sdl.Quit()
|
|
|
|
|
2019-08-03 05:14:56 +00:00
|
|
|
env := core.NewEnvironment(*width, *height)
|
|
|
|
turtles := make([]*core.Turtle, *numTurtles)
|
2019-08-10 02:47:26 +00:00
|
|
|
g := graphics.NewGraphics(int32(*width), int32(*height), int32(*pxsize))
|
2019-08-03 02:00:33 +00:00
|
|
|
|
|
|
|
switch *model {
|
|
|
|
|
|
|
|
case "swarm":
|
|
|
|
// Create 2 food blocks
|
2019-08-03 05:14:56 +00:00
|
|
|
for x := 100; x < 110; x++ {
|
|
|
|
for y := 100; y < 110; y++ {
|
|
|
|
env.PutValue(x, y)
|
2019-08-03 02:00:33 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-03 05:14:56 +00:00
|
|
|
for x := 200; x < 210; x++ {
|
|
|
|
for y := 200; y < 210; y++ {
|
|
|
|
env.PutValue(x, y)
|
2019-08-03 02:00:33 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-03 05:14:56 +00:00
|
|
|
for i := 0; i < *numTurtles; i++ {
|
|
|
|
turtles[i] = core.NewTurtle(env, &actors.Ant{SniffDistance: 3, Carrying: false})
|
2019-08-03 02:00:33 +00:00
|
|
|
}
|
2019-08-03 17:46:48 +00:00
|
|
|
env.InitPheromone("food")
|
|
|
|
g.ColorPheromone("food", [4]uint8{0x81, 0x81, 0x12, 0x00})
|
2019-08-03 02:00:33 +00:00
|
|
|
case "woodchips":
|
2019-08-03 05:14:56 +00:00
|
|
|
for x := 0; x < *numTurtles; x++ {
|
2019-08-03 02:00:33 +00:00
|
|
|
env.PutValue(rand.Intn(*width), rand.Intn(*height))
|
|
|
|
}
|
|
|
|
|
2019-08-03 05:14:56 +00:00
|
|
|
for x := 200; x < 210; x++ {
|
|
|
|
for y := 200; y < 210; y++ {
|
|
|
|
env.PutValue(x, y)
|
2019-08-03 02:00:33 +00:00
|
|
|
}
|
|
|
|
}
|
2019-08-03 05:14:56 +00:00
|
|
|
for i := 0; i < *numTurtles; i++ {
|
|
|
|
turtles[i] = core.NewTurtle(env, &actors.WoodChips{SniffDistance: 20, Carrying: false})
|
2019-08-03 02:00:33 +00:00
|
|
|
}
|
|
|
|
case "slimemold":
|
2019-08-03 05:14:56 +00:00
|
|
|
for i := 0; i < *numTurtles; i++ {
|
2019-08-03 05:37:33 +00:00
|
|
|
turtles[i] = core.NewTurtle(env, &actors.SlimeMold{SniffDistance: 5})
|
2019-08-03 02:00:33 +00:00
|
|
|
}
|
2019-08-03 17:46:48 +00:00
|
|
|
env.InitPheromone("trail")
|
|
|
|
g.ColorPheromone("trail", [4]uint8{0x81, 0, 0x81, 0x00})
|
|
|
|
|
2019-08-03 02:00:33 +00:00
|
|
|
default:
|
2019-08-03 05:14:56 +00:00
|
|
|
for i := 0; i < *numTurtles; i++ {
|
|
|
|
turtles[i] = core.NewTurtle(env, &actors.SlimeMold{SniffDistance: 20})
|
2019-08-03 02:00:33 +00:00
|
|
|
}
|
2019-08-04 00:08:38 +00:00
|
|
|
env.InitPheromone("trail")
|
|
|
|
g.ColorPheromone("trail", [4]uint8{0x81, 0, 0x81, 0x00})
|
2019-08-03 02:00:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
running := true
|
|
|
|
wait := sync.WaitGroup{}
|
|
|
|
|
|
|
|
wait.Add(1)
|
|
|
|
go func() {
|
|
|
|
for running {
|
|
|
|
g.Render(env, turtles)
|
|
|
|
}
|
|
|
|
wait.Done()
|
|
|
|
}()
|
|
|
|
|
|
|
|
wait.Add(1)
|
|
|
|
for running {
|
|
|
|
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
|
|
|
switch event.(type) {
|
|
|
|
case *sdl.QuitEvent:
|
|
|
|
running = false
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
wait.Done()
|
|
|
|
wait.Wait()
|
|
|
|
}
|