Browse Source

Much nicer flocking simulation

master
Sarah Jamie Lewis 2 months ago
parent
commit
06da955b21

+ 107
- 0
experiments/flocking/flocking.go View File

@@ -0,0 +1,107 @@
package main

import (
"flag"
"git.openprivacy.ca/sarah/microworlds/core"
"git.openprivacy.ca/sarah/microworlds/experiments"
"github.com/faiface/pixel/pixelgl"
"github.com/foolusion/quadtree"
"image/color"
"math/rand"
"time"
)

var sniffDistance = flag.Int("sniffDistance", 3, "the distance a turtle can detect pheromone levels from")

var W = 1
var envmap = [][]int{
{W, W, W, W, W, W, W, W, W, W, W, W, W, W, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, W, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, W, 0, 0, W, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, W, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, W, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, W},
{W, W, W, W, W, W, W, W, W, W, W, W, W, W, W},
}

type Bird struct {
}

func (sm *Bird) Setup(env *core.Environment, t *core.Turtle) {
t.SetColor(color.RGBA{100, 255, 10, 0})
t.SetHeading(rand.Intn(8 ))
}

var searchtree = quadtree.XY{4, 4}

func (sm *Bird) Run(env *core.Environment, t *core.Turtle) {
//t.Wiggle()

t.FollowAverageGradient(env, 50,0.1, "bird")
t.RejectGradient(env, 0, "bird")

if !t.Step(env) {
//t.TurnAround()
t.Wiggle()
t.Wiggle()
t.Wiggle()
}

x, y := t.Pos()
center := quadtree.NewXY(float64(x), float64(y))
neighbours := env.GetNearestNeighbours(quadtree.NewAABB(*center, searchtree), 3)

if len(neighbours) > 2 {
//t.SetHeading(avgHead % 8)
// t.Wiggle()
} else {
t.Wiggle()
}

t.Drop(env, 1, "bird")
}

func mainrun() {
experiment := new(experiments.Experiment)
experiment.InitializeExperiment()
t := new(core.Turtle)
t.SetColor(color.RGBA{255, 0, 0, 255})
experiment.InitEnvironment(func(environment *core.Environment) {
// Create 2 food piles

for x := 0; x < 300; x++ {
for y := 0; y < 300; y++ {
if envmap[y/20][x/20] == 1 {
//if ((x %20 < 10) && (y% 20<10)) || x < 30 || y < 30 || y > 270 || x > 270 || (x <100 && y>200) || ((x>150 && x < 300) && (y > 150 && y<175)) || ((x>150 && x < 180) && (y > 100 && y<175)){
environment.Occupy(t, x, y)
environment.PutValue(x,y)
}
}
}
})

experiment.InitNTurtles(func() core.Actor {
sm := new(Bird)

return sm
},1000)

experiment.InitPheromone("bird", color.RGBA{0x80, 0xaa, 0x00, 0x00})
experiment.OnStep = func(environment *core.Environment, turtles []*core.Turtle, i int) {
environment.EvaporateAndDiffuse(0.90, "bird")
}
experiment.Run()
}

func main() {
rand.Seed(time.Now().UnixNano())
pixelgl.Run(mainrun)
}

+ 0
- 66
experiments/flocking/main.go View File

@@ -1,66 +0,0 @@
package main

import (
"flag"
"git.openprivacy.ca/sarah/microworlds/core"
"git.openprivacy.ca/sarah/microworlds/experiments"
"github.com/faiface/pixel/pixelgl"
"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 mainrun() {
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()
}

func main() {
pixelgl.Run(mainrun)
}

+ 6
- 7
experiments/predatorprey/predprey.go View File

@@ -149,24 +149,23 @@ func mainrun() {
}

x = append(x, float64(environment.Step))
prey = append(prey, float64(preyalive))
pred = append(pred, float64(predalive))
prey = append(prey, 100*(float64(preyalive)/float64(environment.Width()*environment.Height())))
pred = append(pred, 100*(float64(predalive)/float64(environment.Width()*environment.Height())))

preypop := chart.ContinuousSeries{
Name: "Prey Population Size",
Name: "Prey Population Density",
XValues: x,
YValues: prey,
}

predpop := chart.ContinuousSeries{
Name: "Predator Population Size",
Name: "Predator Population Density",
XValues: x,
YValues: pred,

}

graph := chart.Chart{
Width: 300,
Height: 300,

Background: chart.Style{
Padding: chart.Box{
@@ -176,7 +175,7 @@ func mainrun() {
XAxis: chart.XAxis{Name: "Time Step", NameStyle: chart.Style{Show: true}, Style: chart.Style{Show: true}, ValueFormatter: func(v interface{}) string {
return fmt.Sprintf("%d", int(v.(float64)))
}},
YAxis: chart.YAxis{Name: "Population", NameStyle: chart.Style{Show: true}, Style: chart.Style{Show: true}, ValueFormatter: func(v interface{}) string {
YAxis: chart.YAxis{Name: "Population", NameStyle: chart.Style{Show: true}, Style: chart.Style{Show: true,}, ValueFormatter: func(v interface{}) string {
return fmt.Sprintf("%d", int(v.(float64)))
}},
Series: []chart.Series{

+ 2
- 2
graphics/graphics.go View File

@@ -57,12 +57,12 @@ func (g *Graphics) ColorPheromone(name string, color [4]uint8) {

func (g *Graphics) Render(env *core.Environment, turtles []*core.Turtle) {
g.imd.Clear()
//g.window.Clear(color.RGBA{0,0,0,0})
g.window.Clear(color.RGBA{0,0,0,0})
pheromoneImage := image.NewRGBA(image.Rect(0, 0, int(g.width), int(g.height)))
for x := 0; x < int(g.width); x++ {
for y := 0; y < int(g.height); y++ {
if env.HasValue(x, y) {
g.DrawTileColor(g.imd, int32(x), int32(y), color.RGBA{255, 255, 255, uint8(255)})
pheromoneImage.SetRGBA(x,y, color.RGBA{255, 0, 128, 0xFF})
} else {
scaledamountRedTotal := 0
scaledamountGreenTotal := 0

Loading…
Cancel
Save