Playing with flocking models
This commit is contained in:
parent
f24484108e
commit
96ad92e5dd
|
@ -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]
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue