Playing with flocking models

This commit is contained in:
Sarah Jamie Lewis 2019-10-25 16:54:23 -07:00
parent f24484108e
commit 96ad92e5dd
2 changed files with 151 additions and 2 deletions

View File

@ -2,6 +2,7 @@ package core
import (
"image/color"
"math"
"math/rand"
)
@ -38,9 +39,9 @@ func NewTurtle(env *Environment, actor Actor) *Turtle {
turtle.actor = actor
turtle.atts = make(map[string]string)
if env.Check(turtle.xpos, turtle.ypos) == false {
turtle.setRandomHeading()
actor.Setup(env, turtle)
env.Occupy(turtle, turtle.xpos, turtle.ypos)
turtle.setRandomHeading()
return turtle
}
}
@ -100,6 +101,11 @@ func (t *Turtle) SetAttribute(name, val string) {
t.atts[name] = val
}
func (t *Turtle) SetHeading(heading int) {
t.heading =heading
}
func (t *Turtle) TurnAround() {
t.heading = (t.heading + 4) % 8
}
@ -246,6 +252,87 @@ func (t *Turtle) FollowGradient(env *Environment, distance int, threshold float3
}
}
func (t *Turtle) AvoidAverageGradient(env *Environment, distance int, threshold float32, pheromone string) {
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) % 8
dx1 := headings[h1][0] * distance
dy1 := headings[h1][1] * distance
x1 := (t.xpos + dx1)
y1 := (t.ypos + dy1)
as0 := env.SniffNormalized(x0, y0, pheromone)
as := env.SniffNormalized(x, y, pheromone)
as1 := env.SniffNormalized(x1, y1, pheromone)
avg := float64((1 * as0) + (2*as) + (3 *as1) / (as0+as+as1))
heading := math.Round(avg)
if heading < 1 && as0 > threshold{
t.heading = h1
} else if heading > 2 && as1 > threshold {
t.heading = h0
}
}
func (t *Turtle) FollowAverageGradient(env *Environment, distance int, threshold float32, pheromone string) {
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) % 8
dx1 := headings[h1][0] * distance
dy1 := headings[h1][1] * distance
x1 := (t.xpos + dx1)
y1 := (t.ypos + dy1)
as0 := env.SniffNormalized(x0, y0, pheromone)
as := env.SniffNormalized(x, y, pheromone)
as1 := env.SniffNormalized(x1, y1, pheromone)
avg := float64((1 * as0) + (2*as) + (3 *as1) / (as0+as+as1))
heading := math.Round(avg)
if heading < 1 && as0 > threshold{
t.heading = h0
} else if heading > 2 && as1 > threshold {
t.heading = h1
}
}
func (t *Turtle) Check(env *Environment) *Turtle {
dx := headings[t.heading][0]
dy := headings[t.heading][1]

View File

@ -1 +1,63 @@
package flocking
package main
import (
"flag"
"git.openprivacy.ca/sarah/microworlds/core"
"git.openprivacy.ca/sarah/microworlds/experiments"
"image/color"
)
var sniffDistance = flag.Int("sniffDistance", 3, "the distance a turtle can detect pheromone levels from")
type Bird struct {
}
func (sm *Bird) Setup(env *core.Environment, t *core.Turtle) {
t.SetColor(color.RGBA{100, 255, 10, 0})
//t.SetHeading(5)
}
func (sm *Bird) Run(env *core.Environment, t *core.Turtle) {
//t.Wiggle()
if t.AmountAll(env,1,"bird") > 1 {
//t.Wiggle()
t.AvoidAverageGradient(env, 1, 2.5, "bird")
//t.Wiggle()
t.Step(env)
t.Drop(env, 2, "bird")
} else if t.AmountAll(env,1,"bird") > 2 {
t.AvoidAverageGradient(env, 1, 1, "bird")
t.Wiggle()
t.Step(env)
t.Drop(env, 1, "bird")
} else {
// t.TurnAround()
// t.Wiggle()
// t.Wiggle()
// t.Wiggle()
t.FollowAverageGradient(env, 5, 1, "bird")
t.FollowAverageGradient(env, 4, 2, "bird")
t.FollowAverageGradient(env, 3, 3, "bird")
//t.FollowAverageGradient(env, 2, 4, "bird")
t.Step(env)
t.Drop(env, 1, "bird")
}
}
func main() {
experiment := new(experiments.Experiment)
experiment.InitializeExperiment()
experiment.InitTurtles(func() core.Actor {
sm := new(Bird)
return sm
})
experiment.InitPheromone("bird", color.RGBA{0x80, 0xaa, 0x00, 0x00})
experiment.OnStep = func(environment *core.Environment, turtles []*core.Turtle, i int) {
environment.EvaporateAndDiffuse(0.99, "bird")
}
experiment.Run()
}