Separate out Evapouration and Diffusion
This commit is contained in:
parent
6a7d283bb7
commit
fc9e8603b5
|
@ -15,6 +15,16 @@ func (e *Environment) Height() int {
|
||||||
return e.height
|
return e.height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e * Environment) GetPheromones() []string {
|
||||||
|
keys := make([]string,len(e.state))
|
||||||
|
i:=0
|
||||||
|
for k,_ := range e.state {
|
||||||
|
keys[i] = k
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
func (e *Environment) InitPheromone(name string) {
|
func (e *Environment) InitPheromone(name string) {
|
||||||
state := make([][]float32, e.width)
|
state := make([][]float32, e.width)
|
||||||
for x := range state {
|
for x := range state {
|
||||||
|
@ -102,23 +112,50 @@ func (e *Environment) normXY(x int, y int) (int, int) {
|
||||||
return x, y
|
return x, y
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Environment) Evaporate(rate float32, pheromone string) {
|
|
||||||
//log.Debugf("Evap")
|
|
||||||
|
|
||||||
_, exists := e.state[pheromone]
|
func (e *Environment) Evaporate(rate float32, pheromone string) {
|
||||||
if !exists {
|
for x := 0; x < e.width; x++ {
|
||||||
e.InitPheromone(pheromone)
|
for y := 0; y < e.height; y++ {
|
||||||
|
e.state[pheromone][x][y] = e.state[pheromone][x][y] * rate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Environment) EvaporateAndDiffuse(rate float32, pheromone string) {
|
||||||
|
pheromoneprev := pheromone + "prev"
|
||||||
|
|
||||||
|
e.state[pheromoneprev] = make([][]float32, e.width)
|
||||||
|
for x := range e.state[pheromoneprev] {
|
||||||
|
e.state[pheromoneprev][x] = make([]float32, e.height)
|
||||||
|
for y := 0; y < e.height; y++ {
|
||||||
|
e.state[pheromoneprev][x][y] = e.state[pheromone][x][y] * rate
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pheromoneMap := e.state[pheromoneprev]
|
||||||
|
for x := 0; x < e.width; x++ {
|
||||||
|
for y := 0; y < e.height; y++ {
|
||||||
|
amount := e.state[pheromoneprev][x][y]
|
||||||
|
|
||||||
|
totalAmount := amount + e.sniffNormalized(x-1, y-1, pheromoneMap) + e.sniffNormalized(x, y-1, pheromoneMap) + e.sniffNormalized(x+1, y-1, pheromoneMap) + e.sniffNormalized(x-1, y, pheromoneMap) + e.sniffNormalized(x+1, y, pheromoneMap)
|
||||||
|
totalAmount += e.sniffNormalized(x-1, y+1, pheromoneMap) + e.sniffNormalized(x, y+1, pheromoneMap) + e.sniffNormalized(x+1, y+1, pheromoneMap)
|
||||||
|
|
||||||
|
e.state[pheromone][x][y] = totalAmount / 9
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *Environment) Diffuse(pheromone string) {
|
||||||
pheromoneprev := pheromone + "prev"
|
pheromoneprev := pheromone + "prev"
|
||||||
|
|
||||||
e.state[pheromoneprev] = make([][]float32, e.width)
|
e.state[pheromoneprev] = make([][]float32, e.width)
|
||||||
for x := range e.state[pheromoneprev] {
|
for x := range e.state[pheromoneprev] {
|
||||||
e.state[pheromoneprev][x] = make([]float32, e.height)
|
e.state[pheromoneprev][x] = make([]float32, e.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
for x := 0; x < e.width; x++ {
|
for x := 0; x < e.width; x++ {
|
||||||
for y := 0; y < e.height; y++ {
|
for y := 0; y < e.height; y++ {
|
||||||
e.state[pheromoneprev][x][y] = e.state[pheromone][x][y] * rate
|
e.state[pheromoneprev][x][y] = e.state[pheromone][x][y]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,23 @@ func (t *Turtle) Drop(env *Environment, amount float32, pheromone string) {
|
||||||
env.Mark(pheromone, t.xpos, t.ypos, amount)
|
env.Mark(pheromone, t.xpos, t.ypos, amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *Turtle) AmountAll(env *Environment, distance int, pheromone string) float32 {
|
||||||
|
total := float32(0)
|
||||||
|
for i:=0;i<8;i++ {
|
||||||
|
dx0 := headings[i][0] * distance
|
||||||
|
dy0 := headings[i][1] * distance
|
||||||
|
|
||||||
|
x0 := (t.xpos + dx0)
|
||||||
|
y0 := (t.ypos + dy0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
total += env.SniffNormalized(x0, y0, pheromone)
|
||||||
|
}
|
||||||
|
|
||||||
|
return total
|
||||||
|
}
|
||||||
|
|
||||||
func (t *Turtle) Amount(env *Environment, distance int, pheromone string) float32 {
|
func (t *Turtle) Amount(env *Environment, distance int, pheromone string) float32 {
|
||||||
h0 := t.heading - 1
|
h0 := t.heading - 1
|
||||||
if h0 < 0 {
|
if h0 < 0 {
|
||||||
|
|
|
@ -25,6 +25,7 @@ type Experiment struct {
|
||||||
turtles []*core.Turtle
|
turtles []*core.Turtle
|
||||||
graphics *graphics.Graphics
|
graphics *graphics.Graphics
|
||||||
initializedTurtles int
|
initializedTurtles int
|
||||||
|
pheromones []string
|
||||||
OnStep func(*core.Environment, []*core.Turtle, int)
|
OnStep func(*core.Environment, []*core.Turtle, int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,8 +47,10 @@ func (e *Experiment) InitializeExperiment() {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
e.OnStep = func(environment *core.Environment, turtles []*core.Turtle, i int) {
|
e.OnStep = func(env *core.Environment, turtles []*core.Turtle, i int) {
|
||||||
|
for _, name := range e.pheromones {
|
||||||
|
env.EvaporateAndDiffuse(0.95, name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e.env = core.NewEnvironment(*width, *height)
|
e.env = core.NewEnvironment(*width, *height)
|
||||||
|
@ -62,6 +65,7 @@ func (e *Experiment) GetNumTurtles() int {
|
||||||
func (e *Experiment) InitPheromone(name string, col color.Color) {
|
func (e *Experiment) InitPheromone(name string, col color.Color) {
|
||||||
e.env.InitPheromone(name)
|
e.env.InitPheromone(name)
|
||||||
r, g, b, a := col.RGBA()
|
r, g, b, a := col.RGBA()
|
||||||
|
e.pheromones = append(e.pheromones, name)
|
||||||
e.graphics.ColorPheromone(name, [4]uint8{uint8(r), uint8(g), uint8(b), uint8(a)})
|
e.graphics.ColorPheromone(name, [4]uint8{uint8(r), uint8(g), uint8(b), uint8(a)})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ func main() {
|
||||||
alive := 0
|
alive := 0
|
||||||
predalive := 0
|
predalive := 0
|
||||||
|
|
||||||
|
env.EvaporateAndDiffuse(0.95, "scent")
|
||||||
// Grow Grass
|
// Grow Grass
|
||||||
x := rand.Intn(env.Width())
|
x := rand.Intn(env.Width())
|
||||||
y := rand.Intn(env.Height())
|
y := rand.Intn(env.Height())
|
||||||
|
|
|
@ -14,7 +14,7 @@ type SlimeMold struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *SlimeMold) Setup(env *core.Environment, t *core.Turtle) {
|
func (sm *SlimeMold) Setup(env *core.Environment, t *core.Turtle) {
|
||||||
// Do nothing
|
t.SetColor(color.RGBA{100,255,10,0})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *SlimeMold) Run(env *core.Environment, t *core.Turtle) {
|
func (sm *SlimeMold) Run(env *core.Environment, t *core.Turtle) {
|
||||||
|
@ -33,5 +33,8 @@ func main() {
|
||||||
return sm
|
return sm
|
||||||
})
|
})
|
||||||
experiment.InitPheromone("trail", color.RGBA{0x80, 0xFF, 0x00, 0x00})
|
experiment.InitPheromone("trail", color.RGBA{0x80, 0xFF, 0x00, 0x00})
|
||||||
|
experiment.OnStep = func(environment *core.Environment, turtles []*core.Turtle, i int) {
|
||||||
|
environment.EvaporateAndDiffuse(0.99, "trail")
|
||||||
|
}
|
||||||
experiment.Run()
|
experiment.Run()
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,10 @@ func (sm *Frog) Setup(env *core.Environment, t *core.Turtle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *Frog) Run(env *core.Environment, t *core.Turtle) {
|
func (sm *Frog) Run(env *core.Environment, t *core.Turtle) {
|
||||||
|
t.FollowGradient(env,1,1,"frog-scent")
|
||||||
t.Wiggle()
|
t.Wiggle()
|
||||||
amountTurtle := t.Amount(env, 1, "turtle-scent")
|
amountTurtle := t.AmountAll(env, 1, "turtle-scent")
|
||||||
amountFrog := t.Amount(env, 1, "frog-scent")
|
amountFrog := t.AmountAll(env, 1, "frog-scent")
|
||||||
if amountFrog > 1 && amountFrog > (amountTurtle+amountFrog)*float32(*frogPreference) {
|
if amountFrog > 1 && amountFrog > (amountTurtle+amountFrog)*float32(*frogPreference) {
|
||||||
// Do Nothing
|
// Do Nothing
|
||||||
} else {
|
} else {
|
||||||
|
@ -45,9 +46,10 @@ func (sm *Turtle) Setup(env *core.Environment, t *core.Turtle) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (sm *Turtle) Run(env *core.Environment, t *core.Turtle) {
|
func (sm *Turtle) Run(env *core.Environment, t *core.Turtle) {
|
||||||
|
t.FollowGradient(env,1,1,"turtle-scent")
|
||||||
t.Wiggle()
|
t.Wiggle()
|
||||||
amountTurtle := t.Amount(env, 1, "turtle-scent")
|
amountTurtle := t.AmountAll(env, 1, "turtle-scent")
|
||||||
amountFrog := t.Amount(env, 1, "frog-scent")
|
amountFrog := t.AmountAll(env, 1, "frog-scent")
|
||||||
if amountTurtle > 1 && amountTurtle > (amountTurtle+amountFrog)*float32(*turtlePreference) {
|
if amountTurtle > 1 && amountTurtle > (amountTurtle+amountFrog)*float32(*turtlePreference) {
|
||||||
// Do Nothing
|
// Do Nothing
|
||||||
} else {
|
} else {
|
||||||
|
@ -74,5 +76,10 @@ func main() {
|
||||||
experiment.InitPheromone("turtle-scent", color.RGBA{0xFF, 0x00, 0x00, 0x00})
|
experiment.InitPheromone("turtle-scent", color.RGBA{0xFF, 0x00, 0x00, 0x00})
|
||||||
experiment.InitPheromone("frog-scent", color.RGBA{0x00, 0xFF, 0xFF, 0x00})
|
experiment.InitPheromone("frog-scent", color.RGBA{0x00, 0xFF, 0xFF, 0x00})
|
||||||
|
|
||||||
|
experiment.OnStep = func(env *core.Environment, turtles []*core.Turtle, i int) {
|
||||||
|
env.Evaporate(.99, "turtle-scent")
|
||||||
|
env.Evaporate(.99, "frog-scent")
|
||||||
|
}
|
||||||
|
|
||||||
experiment.Run()
|
experiment.Run()
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
|
||||||
// "strconv"
|
// "strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -98,14 +97,9 @@ func (g *Graphics) Render(env *core.Environment, turtles []*core.Turtle) {
|
||||||
t.Run(env)
|
t.Run(env)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Move this into an environment specification
|
|
||||||
for name := range g.colorMap {
|
|
||||||
env.Evaporate(0.95, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
g.renderer.Present()
|
g.renderer.Present()
|
||||||
g.window.UpdateSurface()
|
g.window.UpdateSurface()
|
||||||
surface, _ := g.window.GetSurface()
|
// surface, _ := g.window.GetSurface()
|
||||||
surface.SaveBMP("./images/" + strconv.Itoa(g.t) + ".bmp")
|
// surface.SaveBMP("./images/" + strconv.Itoa(g.t) + ".bmp")
|
||||||
g.t++
|
g.t++
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue