forked from sarah/microworlds
Initial Commit
This commit is contained in:
parent
c7ca6fb865
commit
b05168892a
|
@ -24,3 +24,6 @@ _testmain.go
|
||||||
*.test
|
*.test
|
||||||
*.prof
|
*.prof
|
||||||
|
|
||||||
|
images/
|
||||||
|
*.gif
|
||||||
|
.idea/
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package actors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.openprivacy.ca/sarah/microworlds/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type Ant struct {
|
||||||
|
SniffDistance int
|
||||||
|
Carrying bool
|
||||||
|
DropSize float32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a * Ant) Setup(env *core.Environment, t *core.Turtle) {
|
||||||
|
//t.SetXY(150,150)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a*Ant) Run(env *core.Environment, t *core.Turtle) {
|
||||||
|
if a.Carrying == false {
|
||||||
|
if env.HasValue(t.Pos()) {
|
||||||
|
env.TakeValue(t.Pos())
|
||||||
|
a.Carrying = true
|
||||||
|
a.DropSize = 100
|
||||||
|
t.TurnAround()
|
||||||
|
} else {
|
||||||
|
t.Wiggle()
|
||||||
|
t.FollowGradient(env, a.SniffDistance, 5)
|
||||||
|
}
|
||||||
|
t.Step(env)
|
||||||
|
} else if a.Carrying == true {
|
||||||
|
a.DropSize -= 0.6
|
||||||
|
t.Drop(env, a.DropSize)
|
||||||
|
t.Wiggle()
|
||||||
|
t.Step(env)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
package actors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.openprivacy.ca/sarah/microworlds/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SlimeMold struct {
|
||||||
|
SniffDistance int
|
||||||
|
}
|
||||||
|
|
||||||
|
func(sm * SlimeMold) Setup(env *core.Environment, t *core.Turtle) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sm * SlimeMold) Run(env *core.Environment, t *core.Turtle) {
|
||||||
|
t.Wiggle()
|
||||||
|
t.FollowGradient(env, sm.SniffDistance, 2)
|
||||||
|
t.Step(env)
|
||||||
|
t.Drop(env, 1)
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package actors
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.openprivacy.ca/sarah/microworlds/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WoodChips struct {
|
||||||
|
SniffDistance int
|
||||||
|
Carrying bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a * WoodChips) Setup(env *core.Environment, t *core.Turtle) {
|
||||||
|
//t.SetXY(150,150)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a*WoodChips) Run(env *core.Environment, t *core.Turtle) {
|
||||||
|
if a.Carrying {
|
||||||
|
if env.HasValue(t.Pos()) {
|
||||||
|
for {
|
||||||
|
t.Wiggle()
|
||||||
|
t.Step(env)
|
||||||
|
if !env.HasValue(t.Pos()){
|
||||||
|
env.PutValue(t.Pos())
|
||||||
|
a.Carrying = false
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if env.HasValue(t.Pos()) {
|
||||||
|
env.TakeValue(t.Pos())
|
||||||
|
a.Carrying = true
|
||||||
|
t.TurnAround()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.Wiggle()
|
||||||
|
t.Step(env)
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
type Actor interface {
|
||||||
|
Setup(*Environment, *Turtle)
|
||||||
|
Run(*Environment, *Turtle)
|
||||||
|
}
|
|
@ -0,0 +1,131 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
type Environment struct {
|
||||||
|
width,height int
|
||||||
|
state [][]float32
|
||||||
|
pstate [][]float32
|
||||||
|
value [][]bool
|
||||||
|
col [][]bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Environment) Width() int {
|
||||||
|
return e.width
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (e *Environment) Height() int {
|
||||||
|
return e.height
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEnvironment(width int, height int) *Environment {
|
||||||
|
env := new(Environment)
|
||||||
|
env.width = width
|
||||||
|
env.height = height
|
||||||
|
env.state = make([][]float32, width)
|
||||||
|
for x := range env.state {
|
||||||
|
env.state[x] = make([]float32, height)
|
||||||
|
}
|
||||||
|
env.col = make([][]bool, width)
|
||||||
|
for x := range env.col {
|
||||||
|
env.col[x] = make([]bool, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
env.value = make([][]bool, width)
|
||||||
|
for x := range env.value {
|
||||||
|
env.value[x] = make([]bool, height)
|
||||||
|
}
|
||||||
|
return env
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Environment) Mark(x,y int,amount float32) {
|
||||||
|
e.state[x][y] = e.state[x][y] + amount
|
||||||
|
if e.state[x][y] > 255 {
|
||||||
|
e.state[x][y] = 255
|
||||||
|
}
|
||||||
|
//log.Debugf("Marking: %d %d %f", x, y, e.state[x][y])
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
func (e Environment) Occupy(x,y int) {
|
||||||
|
e.col[x][y] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Environment) Check(x,y int) bool {
|
||||||
|
return e.col[x][y]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Environment) Leave(x,y int) {
|
||||||
|
e.col[x][y] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (e Environment) HasValue(x,y int) bool {
|
||||||
|
return e.value[x][y]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Environment) PutValue(x,y int) {
|
||||||
|
e.value[x][y] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Environment) TakeValue(x,y int) {
|
||||||
|
e.value[x][y] = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e Environment) Sniff(x,y int) float32 {
|
||||||
|
return e.state[x][y]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (e *Environment) normXY(x int, y int) (int,int) {
|
||||||
|
if x < 0 {
|
||||||
|
x = (e.width - 1)
|
||||||
|
} else if x >= e.width {
|
||||||
|
x = x % (e.width )
|
||||||
|
}
|
||||||
|
|
||||||
|
if y< 0 {
|
||||||
|
y = (e.height - 1)
|
||||||
|
} else if y >= e.height {
|
||||||
|
y = y % (e.height)
|
||||||
|
}
|
||||||
|
|
||||||
|
return x,y
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Environment) Evaporate(rate float32) {
|
||||||
|
//log.Debugf("Evap")
|
||||||
|
|
||||||
|
|
||||||
|
e.pstate = make([][]float32, e.width)
|
||||||
|
for x := range e.pstate {
|
||||||
|
e.pstate[x] = make([]float32, e.height)
|
||||||
|
}
|
||||||
|
for x:=0;x<e.width;x++ {
|
||||||
|
for y := 0; y < e.height; y++ {
|
||||||
|
e.pstate[x][y] = e.state[x][y] * rate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for x:=0;x<e.width;x++ {
|
||||||
|
for y:=0;y<e.height;y++ {
|
||||||
|
amount := e.pstate[x][y]
|
||||||
|
|
||||||
|
totalAmount := amount + e.NormalizeSniff(x-1,y-1) + e.NormalizeSniff(x,y-1) + e.NormalizeSniff(x+1,y-1) + e.NormalizeSniff(x-1,y) + e.NormalizeSniff(x+1,y)
|
||||||
|
totalAmount += e.NormalizeSniff(x-1,y+1) + e.NormalizeSniff(x,y+1) +e.NormalizeSniff(x+1,y+1)
|
||||||
|
|
||||||
|
e.state[x][y] = totalAmount/9
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Environment) SniffNormalized(x int, y int) float32 {
|
||||||
|
x,y = e.normXY(x,y)
|
||||||
|
return e.state[x][y]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Environment) NormalizeSniff(x int, y int) float32 {
|
||||||
|
x,y = e.normXY(x,y)
|
||||||
|
return e.pstate[x][y]
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestEnvironment_Mark(t *testing.T) {
|
||||||
|
env := NewEnvironment(3,3)
|
||||||
|
env.Mark(1,1,9)
|
||||||
|
env.Evaporate()
|
||||||
|
for x:=0;x<3;x++ {
|
||||||
|
for y:=0;y<3;y++ {
|
||||||
|
t.Logf("mark(%d,%d) = %f", x,y,env.Sniff(x,y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("\n")
|
||||||
|
env.Evaporate()
|
||||||
|
for x:=0;x<3;x++ {
|
||||||
|
for y:=0;y<3;y++ {
|
||||||
|
t.Logf("mark(%d,%d) = %f", x,y,env.Sniff(x,y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Turtle struct {
|
||||||
|
xpos, ypos int
|
||||||
|
heading int
|
||||||
|
actor Actor
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func NewTurtle(env *Environment, actor Actor) *Turtle {
|
||||||
|
for {
|
||||||
|
turtle := new(Turtle)
|
||||||
|
turtle.xpos = rand.Intn(env.width)
|
||||||
|
turtle.ypos = rand.Intn(env.height)
|
||||||
|
turtle.actor = actor
|
||||||
|
if env.Check(turtle.xpos, turtle.ypos) == false {
|
||||||
|
actor.Setup(env,turtle)
|
||||||
|
env.Occupy(turtle.xpos, turtle.ypos)
|
||||||
|
turtle.setRandomHeading()
|
||||||
|
return turtle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Turtle) Pos() (int,int) {
|
||||||
|
return t.xpos,t.ypos
|
||||||
|
}
|
||||||
|
|
||||||
|
var headings = [][]int{{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0}}
|
||||||
|
|
||||||
|
|
||||||
|
func (t *Turtle) setRandomHeading() {
|
||||||
|
t.heading = rand.Intn(7)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Turtle) SetXY(x,y int) {
|
||||||
|
t.xpos = x
|
||||||
|
t.ypos = y
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Turtle) Wiggle() {
|
||||||
|
wiggle := rand.Intn(3) - 1
|
||||||
|
h := (t.heading + wiggle) % 8
|
||||||
|
if h < 0 {
|
||||||
|
h = 7
|
||||||
|
}
|
||||||
|
t.heading = h
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (t*Turtle) TurnAround() {
|
||||||
|
t.heading = (t.heading + 4) % 8
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (t*Turtle) Drop(env *Environment, amount float32) {
|
||||||
|
env.Mark(t.xpos,t.ypos, amount)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *Turtle) FollowGradient(env *Environment, distance int, threshold float32 ) {
|
||||||
|
|
||||||
|
h0 := t.heading-1
|
||||||
|
if h0 < 0 {
|
||||||
|
h0 = 7
|
||||||
|
}
|
||||||
|
|
||||||
|
dx0 := headings[h0][0] * distance
|
||||||
|
dy0 := headings[h0][1] * distance
|
||||||
|
|
||||||
|
x0 := (t.xpos + dx0)
|
||||||
|
y0 := (t.ypos + dy0)
|
||||||
|
|
||||||
|
dx := headings[t.heading][0] * distance
|
||||||
|
dy := headings[t.heading][1] * distance
|
||||||
|
|
||||||
|
x := (t.xpos + dx)
|
||||||
|
y := (t.ypos + dy)
|
||||||
|
|
||||||
|
|
||||||
|
h1 := (t.heading+1) % 7
|
||||||
|
dx1 := headings[h1][0] * distance
|
||||||
|
dy1 := headings[h1][1] * distance
|
||||||
|
|
||||||
|
x1 := (t.xpos + dx1)
|
||||||
|
y1 := (t.ypos + dy1)
|
||||||
|
|
||||||
|
as0 := env.SniffNormalized(x0,y0)
|
||||||
|
if as0 < threshold {
|
||||||
|
as0 = 0
|
||||||
|
}
|
||||||
|
as := env.SniffNormalized(x,y)
|
||||||
|
if as < threshold {
|
||||||
|
as = 0
|
||||||
|
}
|
||||||
|
as1 := env.SniffNormalized(x1,y1)
|
||||||
|
if as1 < threshold {
|
||||||
|
as1 = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if as0 > as && as0 > as1{
|
||||||
|
t.heading = h0
|
||||||
|
} else if as1 > as && as1 > as0 {
|
||||||
|
t.heading = h1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t* Turtle) Step(env *Environment) bool {
|
||||||
|
dx := headings[t.heading][0]
|
||||||
|
dy := headings[t.heading][1]
|
||||||
|
|
||||||
|
ox := t.xpos
|
||||||
|
oy := t.ypos
|
||||||
|
env.Leave(ox,oy)
|
||||||
|
t.xpos = (t.xpos + dx) % (env.width -1)
|
||||||
|
if t.xpos < 0 {
|
||||||
|
t.xpos = env.width-1
|
||||||
|
}
|
||||||
|
t.ypos = (t.ypos + dy) % (env.height -1)
|
||||||
|
if t.ypos < 0 {
|
||||||
|
t.ypos = env.height-1
|
||||||
|
}
|
||||||
|
|
||||||
|
success := true
|
||||||
|
if env.Check(t.xpos,t.ypos) == true {
|
||||||
|
t.xpos = ox
|
||||||
|
t.ypos = oy
|
||||||
|
success = false
|
||||||
|
}
|
||||||
|
env.Occupy(t.xpos,t.ypos)
|
||||||
|
return success
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the turtle program
|
||||||
|
func (t * Turtle) Run(env * Environment) {
|
||||||
|
//log.Debugf("Pos: %v %v", t.xpos, t.ypos)
|
||||||
|
t.actor.Run(env, t)
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestTurtle_Wiggle(t *testing.T) {
|
||||||
|
turtle := NewTurtle(NewEnvironment(3,3,))
|
||||||
|
counts := []int{0,0,0,0,0,0,0,0}
|
||||||
|
for i:=0;i<1000;i++ {
|
||||||
|
turtle.Wiggle()
|
||||||
|
//t.Logf("Heading %v", turtle.heading)
|
||||||
|
counts[turtle.heading]++
|
||||||
|
}
|
||||||
|
t.Logf("Heading %v", counts)
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package graphics
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"git.openprivacy.ca/sarah/microworlds/core"
|
||||||
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
|
"math"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Graphics struct {
|
||||||
|
window *sdl.Window
|
||||||
|
renderer *sdl.Renderer
|
||||||
|
width, height int32
|
||||||
|
t int
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGraphics(width, height int32) *Graphics {
|
||||||
|
graphics := new(Graphics)
|
||||||
|
graphics.width = width
|
||||||
|
graphics.height= height
|
||||||
|
window, err := sdl.CreateWindow("Microworlds", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
|
||||||
|
width, height, sdl.WINDOW_SHOWN)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
graphics.window = window
|
||||||
|
|
||||||
|
surface,_ := window.GetSurface()
|
||||||
|
renderer, err := sdl.CreateSoftwareRenderer(surface)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
graphics.renderer = renderer
|
||||||
|
return graphics
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g* Graphics) Render(env *core.Environment, turtles []*core.Turtle) {
|
||||||
|
g.renderer.SetDrawColor(0x00,0x00,0x00,0x00)
|
||||||
|
g.renderer.FillRect(&sdl.Rect{0,0,600,600})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
for x:=0;x<int(g.width);x++ {
|
||||||
|
for y:=0;y<int(g.height);y++ {
|
||||||
|
amount := math.Min(float64(env.Sniff(x,y)), 255)
|
||||||
|
|
||||||
|
if amount > 0 {
|
||||||
|
col := uint8(amount*0x81)
|
||||||
|
if col > 0x81 {
|
||||||
|
col = 0x81
|
||||||
|
}
|
||||||
|
g.renderer.SetDrawColor(col,0,col, uint8(255) )
|
||||||
|
g.renderer.DrawPoint(int32(x), int32(y))
|
||||||
|
}
|
||||||
|
|
||||||
|
if env.HasValue(x,y) {
|
||||||
|
g.renderer.SetDrawColor(255,255,255, uint8(255) )
|
||||||
|
g.renderer.DrawPoint(int32(x), int32(y))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
g.renderer.SetDrawColor(0xF3,0x81,0,0x00)
|
||||||
|
for _,t := range turtles {
|
||||||
|
x,y := t.Pos()
|
||||||
|
g.renderer.DrawPoint(int32(x),int32(y))
|
||||||
|
t.Run(env)
|
||||||
|
}
|
||||||
|
env.Evaporate(0.95)
|
||||||
|
|
||||||
|
g.renderer.Present()
|
||||||
|
g.window.UpdateSurface()
|
||||||
|
surface,_ := g.window.GetSurface()
|
||||||
|
surface.SaveBMP("./images/"+ strconv.Itoa(g.t)+".bmp")
|
||||||
|
g.t++;
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
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")
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
env := core.NewEnvironment(*width,*height)
|
||||||
|
turtles := make([]*core.Turtle,*numTurtles)
|
||||||
|
|
||||||
|
|
||||||
|
switch *model {
|
||||||
|
|
||||||
|
case "swarm":
|
||||||
|
// Create 2 food blocks
|
||||||
|
for x:= 100;x<110;x++ {
|
||||||
|
for y:= 100;y<110;y++ {
|
||||||
|
env.PutValue(x,y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for x:= 200;x<210;x++ {
|
||||||
|
for y:= 200;y<210;y++ {
|
||||||
|
env.PutValue(x,y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i:=0;i<*numTurtles;i++ {
|
||||||
|
turtles[i] = core.NewTurtle(env, &actors.Ant{SniffDistance:3, Carrying:false})
|
||||||
|
}
|
||||||
|
case "woodchips":
|
||||||
|
for x := 0;x<*numTurtles;x++ {
|
||||||
|
env.PutValue(rand.Intn(*width), rand.Intn(*height))
|
||||||
|
}
|
||||||
|
|
||||||
|
for x:= 200;x<210;x++ {
|
||||||
|
for y:= 200;y<210;y++ {
|
||||||
|
env.PutValue(x,y)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i:=0;i<*numTurtles;i++ {
|
||||||
|
turtles[i] = core.NewTurtle(env, &actors.WoodChips{SniffDistance:20, Carrying:false})
|
||||||
|
}
|
||||||
|
case "slimemold":
|
||||||
|
for i:=0;i<*numTurtles;i++ {
|
||||||
|
turtles[i] = core.NewTurtle(env, &actors.SlimeMold{SniffDistance:20})
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
for i:=0;i<*numTurtles;i++ {
|
||||||
|
turtles[i] = core.NewTurtle(env, &actors.SlimeMold{SniffDistance:20})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
g := graphics.NewGraphics(int32(*width),int32(*height))
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue