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) }