Separate out Evapouration and Diffusion

This commit is contained in:
Sarah Jamie Lewis 2019-09-29 15:32:54 -07:00
parent 6a7d283bb7
commit fc9e8603b5
7 changed files with 84 additions and 21 deletions

View File

@ -15,6 +15,16 @@ func (e *Environment) Height() int {
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) {
state := make([][]float32, e.width)
for x := range state {
@ -102,23 +112,50 @@ func (e *Environment) normXY(x int, y int) (int, int) {
return x, y
}
func (e *Environment) Evaporate(rate float32, pheromone string) {
//log.Debugf("Evap")
_, exists := e.state[pheromone]
if !exists {
e.InitPheromone(pheromone)
func (e *Environment) Evaporate(rate float32, pheromone string) {
for x := 0; x < e.width; x++ {
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"
e.state[pheromoneprev] = make([][]float32, e.width)
for x := range e.state[pheromoneprev] {
e.state[pheromoneprev][x] = make([]float32, e.height)
}
for x := 0; x < e.width; x++ {
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]
}
}

View File

@ -108,6 +108,23 @@ func (t *Turtle) Drop(env *Environment, amount float32, pheromone string) {
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 {
h0 := t.heading - 1
if h0 < 0 {

View File

@ -25,6 +25,7 @@ type Experiment struct {
turtles []*core.Turtle
graphics *graphics.Graphics
initializedTurtles int
pheromones []string
OnStep func(*core.Environment, []*core.Turtle, int)
}
@ -46,8 +47,10 @@ func (e *Experiment) InitializeExperiment() {
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)
@ -62,6 +65,7 @@ func (e *Experiment) GetNumTurtles() int {
func (e *Experiment) InitPheromone(name string, col color.Color) {
e.env.InitPheromone(name)
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)})
}

View File

@ -115,6 +115,7 @@ func main() {
alive := 0
predalive := 0
env.EvaporateAndDiffuse(0.95, "scent")
// Grow Grass
x := rand.Intn(env.Width())
y := rand.Intn(env.Height())

View File

@ -14,7 +14,7 @@ type SlimeMold struct {
}
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) {
@ -33,5 +33,8 @@ func main() {
return sm
})
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()
}

View File

@ -22,9 +22,10 @@ func (sm *Frog) Setup(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()
amountTurtle := t.Amount(env, 1, "turtle-scent")
amountFrog := t.Amount(env, 1, "frog-scent")
amountTurtle := t.AmountAll(env, 1, "turtle-scent")
amountFrog := t.AmountAll(env, 1, "frog-scent")
if amountFrog > 1 && amountFrog > (amountTurtle+amountFrog)*float32(*frogPreference) {
// Do Nothing
} 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) {
t.FollowGradient(env,1,1,"turtle-scent")
t.Wiggle()
amountTurtle := t.Amount(env, 1, "turtle-scent")
amountFrog := t.Amount(env, 1, "frog-scent")
amountTurtle := t.AmountAll(env, 1, "turtle-scent")
amountFrog := t.AmountAll(env, 1, "frog-scent")
if amountTurtle > 1 && amountTurtle > (amountTurtle+amountFrog)*float32(*turtlePreference) {
// Do Nothing
} else {
@ -74,5 +76,10 @@ func main() {
experiment.InitPheromone("turtle-scent", color.RGBA{0xFF, 0x00, 0x00, 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()
}

View File

@ -6,7 +6,6 @@ import (
"github.com/veandco/go-sdl2/sdl"
"math"
"os"
"strconv"
// "strconv"
)
@ -98,14 +97,9 @@ func (g *Graphics) Render(env *core.Environment, turtles []*core.Turtle) {
t.Run(env)
}
// TODO: Move this into an environment specification
for name := range g.colorMap {
env.Evaporate(0.95, name)
}
g.renderer.Present()
g.window.UpdateSurface()
surface, _ := g.window.GetSurface()
surface.SaveBMP("./images/" + strconv.Itoa(g.t) + ".bmp")
// surface, _ := g.window.GetSurface()
// surface.SaveBMP("./images/" + strconv.Itoa(g.t) + ".bmp")
g.t++
}