From f222cf86b5556b5fe0cc1280518f6de0c3f26745 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Sat, 10 Aug 2019 14:56:49 -0700 Subject: [PATCH] More exampels, upgrading color --- .gitignore | 1 + actors/flocking.go | 35 +++++++++++++++++++++++++++++++++ actors/maze.go | 23 ++++++++++++++++++++++ actors/slush.go | 28 +++++++++++++++++++++++++++ core/turtle.go | 46 ++++++++++++++++++++++++++++++++++++++++++++ graphics/graphics.go | 21 +++++++++++++++----- main.go | 22 +++++++++++++++++++++ 7 files changed, 171 insertions(+), 5 deletions(-) create mode 100644 actors/flocking.go create mode 100644 actors/maze.go create mode 100644 actors/slush.go diff --git a/.gitignore b/.gitignore index cf38b61..829685c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/vendor/ # ---> Go # Compiled Object files, Static and Dynamic libs (Shared Objects) *.o diff --git a/actors/flocking.go b/actors/flocking.go new file mode 100644 index 0000000..8f4a9bf --- /dev/null +++ b/actors/flocking.go @@ -0,0 +1,35 @@ +package actors + +import ( +"git.openprivacy.ca/sarah/microworlds/core" +) + + +type Flocking struct { + SniffDistance int +} + +func (sm *Flocking) Setup(env *core.Environment, t *core.Turtle) { + // Do nothing +} + +func (sm *Flocking) Run(env *core.Environment, t *core.Turtle) { + if t.Near(env, 1,1, "avoid") { + t.TurnAround() + t.Step(env) + } else if t.Near(env, 2,1, "avoid") { + t.TurnAround() + t.Step(env) + } else { + t.FollowGradient(env, 4, 1, "trail") + t.FollowGradient(env, 3, 1,"trail") + t.FollowGradient(env, 2,1, "trail") + t.FollowGradient(env, 1, 3, "trail") + t.Wiggle() + t.Step(env) + } + t.Drop(env, 1, "trail") + t.Drop(env, 2, "avoid") +} + + diff --git a/actors/maze.go b/actors/maze.go new file mode 100644 index 0000000..d0cb769 --- /dev/null +++ b/actors/maze.go @@ -0,0 +1,23 @@ +package actors + +import ( + "git.openprivacy.ca/sarah/microworlds/core" +) + + +type MazeGeneration struct { + SniffDistance int +} + +func (sm *MazeGeneration) Setup(env *core.Environment, t *core.Turtle) { + // Do nothing +} + +func (sm *MazeGeneration) Run(env *core.Environment, t *core.Turtle) { + t.Wiggle() + t.FollowGradient(env, sm.SniffDistance, 0, "trail") + t.TurnAround() // Run away from the strongest trail + t.Step(env) + t.Drop(env, 1, "trail") +} + diff --git a/actors/slush.go b/actors/slush.go new file mode 100644 index 0000000..da0adb4 --- /dev/null +++ b/actors/slush.go @@ -0,0 +1,28 @@ +package actors + +import ( + "git.openprivacy.ca/sarah/microworlds/core" + "math/rand" + "strconv" +) + +type Slush struct { + color int +} + +func (sm *Slush) Setup(env *core.Environment, t *core.Turtle) { + sm.color = rand.Intn(2) + 1 +} + +func (sm *Slush) Run(env *core.Environment, t *core.Turtle) { + t.Wiggle() + if t.Near(env, 1,2, "1") { + sm.color = 1 + } else if t.Near(env, 1,2, "2") { + sm.color = 2 + } + t.Step(env) + t.Drop(env, 1, strconv.Itoa(sm.color)) +} + + diff --git a/core/turtle.go b/core/turtle.go index 5d3bf16..269aaa8 100644 --- a/core/turtle.go +++ b/core/turtle.go @@ -67,6 +67,52 @@ func (t *Turtle) Drop(env *Environment, amount float32, pheromone string) { env.Mark(pheromone, t.xpos, t.ypos, amount) } +func (t *Turtle) Near(env *Environment, distance int, threshold float32, pheromone string) bool { + 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) + if as0 < threshold { + as0 = 0 + } + as := env.SniffNormalized(x, y, pheromone) + if as < threshold { + as = 0 + } + as1 := env.SniffNormalized(x1, y1, pheromone) + if as1 < threshold { + as1 = 0 + } + + if as0 == 0 && as == 0 && as1 == 0 { + return false + } else { + return true + } + +} + func (t *Turtle) FollowGradient(env *Environment, distance int, threshold float32, pheromone string) { h0 := t.heading - 1 diff --git a/graphics/graphics.go b/graphics/graphics.go index 5a5e2c8..16884fc 100644 --- a/graphics/graphics.go +++ b/graphics/graphics.go @@ -6,6 +6,8 @@ import ( "github.com/veandco/go-sdl2/sdl" "math" "os" + "strconv" + //"strconv" ) @@ -56,17 +58,26 @@ func (g *Graphics) Render(env *core.Environment, turtles []*core.Turtle) { for x := 0; x < int(g.width); x++ { for y := 0; y < int(g.height); y++ { + scaledamountRedTotal := 0 + scaledamountGreenTotal := 0 + scaledamountBlueTotal := 0 for name, color := range g.colorMap { amount := math.Min(float64(env.Sniff(name, x, y)), 255) if amount > 0 { // TODO explictly define this scale - scaledamount := uint8(float64(color[0]) * (amount/2)) - g.renderer.SetDrawColor(scaledamount,0,scaledamount, uint8(0xF0)) - g.DrawTileColor(int32(x), int32(y)) + scaledamountRed := uint8(float64(color[0]) * (amount/2)) + scaledamountGreen := uint8(float64(color[1]) * (amount/2)) + scaledamountBlue := uint8(float64(color[2]) * (amount/2)) + scaledamountRedTotal += int(scaledamountRed) + scaledamountGreenTotal += int(scaledamountGreen) + scaledamountBlueTotal += int(scaledamountBlue) } } + g.renderer.SetDrawColor(uint8(scaledamountRedTotal/len(g.colorMap)),uint8(scaledamountGreenTotal/len(g.colorMap)),uint8(scaledamountBlueTotal/len(g.colorMap)), uint8(0xF0)) + g.renderer.DrawPoint(int32(x), int32(y)) + if env.HasValue(x, y) { g.renderer.SetDrawColor(255, 255, 255, uint8(255)) g.DrawTileColor(int32(x), int32(y)) @@ -88,7 +99,7 @@ func (g *Graphics) Render(env *core.Environment, turtles []*core.Turtle) { 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++ } diff --git a/main.go b/main.go index 6ffba56..86533a3 100644 --- a/main.go +++ b/main.go @@ -85,6 +85,28 @@ func main() { } env.InitPheromone("trail") g.ColorPheromone("trail", [4]uint8{0x81, 0, 0x81, 0x00}) + case "maze": + for i := 0; i < *numTurtles; i++ { + turtles[i] = core.NewTurtle(env, &actors.MazeGeneration{SniffDistance: 5}) + } + env.InitPheromone("trail") + g.ColorPheromone("trail", [4]uint8{0x81, 0, 0x81, 0x00}) + case "slush": + for i := 0; i < *numTurtles; i++ { + turtles[i] = core.NewTurtle(env, &actors.Slush{}) + } + env.InitPheromone("1") + env.InitPheromone("2") + g.ColorPheromone("1", [4]uint8{0x00, 0xFF, 0x00, 0x00}) + g.ColorPheromone("2", [4]uint8{0x00, 0, 0xFF, 0x00}) + case "flocking": + for i := 0; i < *numTurtles; i++ { + turtles[i] = core.NewTurtle(env, &actors.Flocking{SniffDistance: 1}) + } + env.InitPheromone("trail") + env.InitPheromone("avoid") + g.ColorPheromone("trail", [4]uint8{0x81, 0, 0x81, 0x00}) + g.ColorPheromone("avoid", [4]uint8{0xd1, 0, 0xff, 0x00}) default: for i := 0; i < *numTurtles; i++ {