143 lines
3.1 KiB
Go
143 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"git.openprivacy.ca/sarah/microworlds/core"
|
|
"git.openprivacy.ca/sarah/microworlds/experiments"
|
|
"github.com/faiface/pixel/pixelgl"
|
|
"github.com/foolusion/quadtree"
|
|
"github.com/wcharczuk/go-chart"
|
|
"image/color"
|
|
"math/rand"
|
|
"os"
|
|
"os/signal"
|
|
"runtime/pprof"
|
|
)
|
|
|
|
var sniffDistance = flag.Int("sniffDistance", 5, "the distance a turtle can detect pheromone levels from")
|
|
|
|
type LightningBug struct {
|
|
Timer int
|
|
HasReset bool
|
|
Num int
|
|
Threshold int
|
|
}
|
|
|
|
func (sm *LightningBug) Setup(env *core.Environment, t *core.Turtle) {
|
|
// Do nothing
|
|
sm.Threshold = 35
|
|
sm.Timer = rand.Intn(sm.Threshold)
|
|
|
|
}
|
|
|
|
var searchtree = quadtree.XY{50, 50}
|
|
|
|
func (sm *LightningBug) Run(env *core.Environment, t *core.Turtle) {
|
|
t.Wiggle()
|
|
|
|
if sm.Timer > 3 {
|
|
t.Step(env)
|
|
}
|
|
|
|
t.SetColor(color.RGBA{0x00, 0x1f, 0x00, 0xff})
|
|
if sm.Timer <= 3 {
|
|
t.SetColor(color.RGBA{0xff, 0xff, 0x00, 0xff})
|
|
}
|
|
|
|
sm.Timer++
|
|
|
|
if sm.Timer > 10 {
|
|
x, y := t.Pos()
|
|
center := quadtree.NewXY(float64(x), float64(y))
|
|
neighbours := env.GetNearestNeighbours(quadtree.NewAABB(*center, searchtree), 3)
|
|
|
|
for _, n := range neighbours {
|
|
if n.GetActor().(*LightningBug).Num != sm.Num && n.GetActor().(*LightningBug).Timer == 0 {
|
|
sm.Timer = 0
|
|
}
|
|
//sm.HasReset = true
|
|
//t.SetColor(color.RGBA{0x00,0x1f,0xff,0xff})
|
|
}
|
|
}
|
|
|
|
if sm.Timer > sm.Threshold {
|
|
sm.Timer = 0
|
|
sm.HasReset = false
|
|
}
|
|
|
|
}
|
|
|
|
func mainrun() {
|
|
experiment := new(experiments.Experiment)
|
|
experiment.InitializeExperiment()
|
|
num := 0
|
|
experiment.InitTurtles(func() core.Actor {
|
|
sm := new(LightningBug)
|
|
sm.Num = num
|
|
num++
|
|
return sm
|
|
})
|
|
|
|
x := []float64{}
|
|
y := []float64{}
|
|
|
|
experiment.AddPlot("Flashing Bugs", func(environment *core.Environment, turtles []*core.Turtle) *chart.Chart {
|
|
numLight := 0.0
|
|
for _, t := range turtles {
|
|
lb := t.GetActor().(*LightningBug)
|
|
if lb.Timer == 0 {
|
|
numLight++
|
|
}
|
|
}
|
|
|
|
x = append(x, float64(environment.Step))
|
|
y = append(y, numLight)
|
|
|
|
graph := chart.Chart{
|
|
Width: 300,
|
|
Height: 300,
|
|
Background: chart.Style{
|
|
Padding: chart.Box{
|
|
Top: 50,
|
|
},
|
|
},
|
|
XAxis: chart.XAxis{Name: "Time Step", NameStyle: chart.Style{Show: true}, Style: chart.Style{Show: true, TextRotationDegrees: 90}, ValueFormatter: func(v interface{}) string {
|
|
return fmt.Sprintf("%d", int(v.(float64)))
|
|
}},
|
|
YAxis: chart.YAxis{Name: "Number of Flashing Lightning Bugs", NameStyle: chart.Style{Show: true}, Style: chart.Style{Show: true}, ValueFormatter: func(v interface{}) string {
|
|
return fmt.Sprintf("%d", int(v.(float64)))
|
|
}},
|
|
Series: []chart.Series{
|
|
chart.ContinuousSeries{
|
|
XValues: x,
|
|
YValues: y,
|
|
},
|
|
},
|
|
}
|
|
return &graph
|
|
})
|
|
|
|
c := make(chan os.Signal, 1)
|
|
signal.Notify(c, os.Interrupt)
|
|
go func() {
|
|
for sig := range c {
|
|
fmt.Printf("Got Signal %v", sig)
|
|
pprof.StopCPUProfile()
|
|
os.Exit(0)
|
|
}
|
|
}()
|
|
|
|
experiment.OnStep = func(environment *core.Environment, turtles []*core.Turtle, i int) {
|
|
environment.Diffuse("light")
|
|
environment.Diffuse("light")
|
|
environment.Evaporate(0.99, "light")
|
|
}
|
|
experiment.InitPheromone("light", color.RGBA{0xff, 0xff, 0x00, 0x00})
|
|
experiment.Run()
|
|
}
|
|
|
|
func main() {
|
|
pixelgl.Run(mainrun)
|
|
}
|