microworlds/experiments/flocking/flocking.go

108 lines
2.8 KiB
Go

package main
import (
"flag"
"git.openprivacy.ca/sarah/microworlds/core"
"git.openprivacy.ca/sarah/microworlds/experiments"
"github.com/faiface/pixel/pixelgl"
"github.com/foolusion/quadtree"
"image/color"
"math/rand"
"time"
)
var sniffDistance = flag.Int("sniffDistance", 3, "the distance a turtle can detect pheromone levels from")
var W = 1
var envmap = [][]int{
{W, W, W, W, W, W, W, W, W, W, W, W, W, W, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, W, 0, 0, W, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, W, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, W, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, W, W, W, W, W, W, W, W, W, W, W, W, W, W},
}
type Bird struct {
}
func (sm *Bird) Setup(env *core.Environment, t *core.Turtle) {
t.SetColor(color.RGBA{100, 255, 10, 0})
t.SetHeading(rand.Intn(8 ))
}
var searchtree = quadtree.XY{4, 4}
func (sm *Bird) Run(env *core.Environment, t *core.Turtle) {
//t.Wiggle()
t.FollowAverageGradient(env, 50,0.1, "bird")
t.RejectGradient(env, 0, "bird")
if !t.Step(env) {
//t.TurnAround()
t.Wiggle()
t.Wiggle()
t.Wiggle()
}
x, y := t.Pos()
center := quadtree.NewXY(float64(x), float64(y))
neighbours := env.GetNearestNeighbours(quadtree.NewAABB(*center, searchtree), 3)
if len(neighbours) > 2 {
//t.SetHeading(avgHead % 8)
// t.Wiggle()
} else {
t.Wiggle()
}
t.Drop(env, 1, "bird")
}
func mainrun() {
experiment := new(experiments.Experiment)
experiment.InitializeExperiment()
t := new(core.Turtle)
t.SetColor(color.RGBA{255, 0, 0, 255})
experiment.InitEnvironment(func(environment *core.Environment) {
// Create 2 food piles
for x := 0; x < 300; x++ {
for y := 0; y < 300; y++ {
if envmap[y/20][x/20] == 1 {
//if ((x %20 < 10) && (y% 20<10)) || x < 30 || y < 30 || y > 270 || x > 270 || (x <100 && y>200) || ((x>150 && x < 300) && (y > 150 && y<175)) || ((x>150 && x < 180) && (y > 100 && y<175)){
environment.Occupy(t, x, y)
environment.PutValue(x,y)
}
}
}
})
experiment.InitNTurtles(func() core.Actor {
sm := new(Bird)
return sm
},1000)
experiment.InitPheromone("bird", color.RGBA{0x80, 0xaa, 0x00, 0x00})
experiment.OnStep = func(environment *core.Environment, turtles []*core.Turtle, i int) {
environment.EvaporateAndDiffuse(0.90, "bird")
}
experiment.Run()
}
func main() {
rand.Seed(time.Now().UnixNano())
pixelgl.Run(mainrun)
}