forked from sarah/microworlds
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
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)})
|
||||
}
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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++
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue