Refactor experiments into separate applications
This commit is contained in:
parent
af28fc7ec0
commit
fe96374bee
|
@ -1,35 +0,0 @@
|
|||
package actors
|
||||
|
||||
import (
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
)
|
||||
|
||||
type Ant struct {
|
||||
SniffDistance int
|
||||
Carrying bool
|
||||
DropSize float32
|
||||
}
|
||||
|
||||
func (a *Ant) Setup(env *core.Environment, t *core.Turtle) {
|
||||
//t.SetXY(150,150)
|
||||
}
|
||||
|
||||
func (a *Ant) Run(env *core.Environment, t *core.Turtle) {
|
||||
if a.Carrying == false {
|
||||
if env.HasValue(t.Pos()) {
|
||||
env.TakeValue(t.Pos())
|
||||
a.Carrying = true
|
||||
a.DropSize = 100
|
||||
t.TurnAround()
|
||||
} else {
|
||||
t.Wiggle()
|
||||
t.FollowGradient(env, a.SniffDistance, 5, "food")
|
||||
}
|
||||
t.Step(env)
|
||||
} else if a.Carrying == true {
|
||||
a.DropSize -= 0.6
|
||||
t.Drop(env, a.DropSize, "food")
|
||||
t.Wiggle()
|
||||
t.Step(env)
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
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")
|
||||
}
|
||||
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
package actors
|
||||
|
||||
import (
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Isolate struct {
|
||||
color int
|
||||
Probability float32
|
||||
sureness float32
|
||||
Byztantine bool
|
||||
}
|
||||
|
||||
func (sm *Isolate) Setup(env *core.Environment, t *core.Turtle) {
|
||||
num := rand.Intn(100)
|
||||
if num >= int(sm.Probability*100.0) {
|
||||
sm.color = 2
|
||||
} else {
|
||||
sm.color = 1
|
||||
}
|
||||
sm.sureness = 2
|
||||
}
|
||||
|
||||
func (sm *Isolate) Run(env *core.Environment, t *core.Turtle) {
|
||||
if sm.Byztantine {
|
||||
t.Wiggle()
|
||||
t.FollowGradient(env, 10,0, "2",)
|
||||
t.Drop(env, 1, "2")
|
||||
t.Step(env)
|
||||
} else {
|
||||
t.Wiggle()
|
||||
am1 := t.Amount(env, 1, "1")
|
||||
am2 := t.Amount(env, 1, "2")
|
||||
|
||||
if am1 > sm.sureness || am2 > sm.sureness {
|
||||
if am1 > am2 {
|
||||
if sm.color == 2 {
|
||||
sm.sureness--
|
||||
} else {
|
||||
sm.sureness++
|
||||
}
|
||||
if sm.sureness == 0 {
|
||||
sm.color = 1
|
||||
}
|
||||
} else if am2 > am1 {
|
||||
if sm.color == 1 {
|
||||
sm.sureness--
|
||||
} else {
|
||||
sm.sureness++
|
||||
}
|
||||
if sm.sureness == 0 {
|
||||
sm.color = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sm.sureness > 1 {
|
||||
t.Drop(env, 1, strconv.Itoa(sm.color))
|
||||
}
|
||||
|
||||
t.Step(env)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
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")
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
package actors
|
||||
|
||||
import (
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
)
|
||||
|
||||
type SlimeMold struct {
|
||||
SniffDistance int
|
||||
}
|
||||
|
||||
func (sm *SlimeMold) Setup(env *core.Environment, t *core.Turtle) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
func (sm *SlimeMold) Run(env *core.Environment, t *core.Turtle) {
|
||||
t.Wiggle()
|
||||
t.FollowGradient(env, sm.SniffDistance, 2, "trail")
|
||||
t.Step(env)
|
||||
t.Drop(env, 1, "trail")
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
package actors
|
||||
|
||||
import (
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Slush struct {
|
||||
color int
|
||||
Probability float32
|
||||
}
|
||||
|
||||
func (sm *Slush) Setup(env *core.Environment, t *core.Turtle) {
|
||||
num := rand.Intn(100)
|
||||
if num >= int(sm.Probability*100.0) {
|
||||
sm.color = 2
|
||||
} else {
|
||||
sm.color = 1
|
||||
}
|
||||
}
|
||||
|
||||
func (sm *Slush) Run(env *core.Environment, t *core.Turtle) {
|
||||
t.Wiggle()
|
||||
am1 := t.Amount(env,1,"1")
|
||||
am2 := t.Amount(env,1,"2")
|
||||
|
||||
t.Drop(env, 1, strconv.Itoa(sm.color))
|
||||
|
||||
|
||||
if am1 > 3 || am2 > 3 {
|
||||
if am1 > am2 {
|
||||
sm.color = 1
|
||||
} else if am2 > am1 {
|
||||
sm.color = 2
|
||||
}
|
||||
}
|
||||
t.Step(env)
|
||||
}
|
||||
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
package actors
|
||||
|
||||
import (
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Snowball struct {
|
||||
color int
|
||||
Probability float32
|
||||
sureness float32
|
||||
Byztantine bool
|
||||
}
|
||||
|
||||
func (sm *Snowball) Setup(env *core.Environment, t *core.Turtle) {
|
||||
num := rand.Intn(100)
|
||||
if num >= int(sm.Probability*100.0) {
|
||||
sm.color = 2
|
||||
} else {
|
||||
sm.color = 1
|
||||
}
|
||||
sm.sureness = 2
|
||||
}
|
||||
|
||||
func (sm *Snowball) Run(env *core.Environment, t *core.Turtle) {
|
||||
if sm.Byztantine {
|
||||
t.Wiggle()
|
||||
t.Drop(env, 1, "2")
|
||||
} else {
|
||||
t.Wiggle()
|
||||
am1 := t.Amount(env, 1, "1")
|
||||
am2 := t.Amount(env, 1, "2")
|
||||
|
||||
if am1 > sm.sureness || am2 > sm.sureness {
|
||||
if am1 > am2 {
|
||||
if sm.color == 2 {
|
||||
sm.sureness--
|
||||
} else {
|
||||
sm.sureness++
|
||||
}
|
||||
if sm.sureness == 0 {
|
||||
sm.color = 1
|
||||
}
|
||||
} else if am2 > am1 {
|
||||
if sm.color == 1 {
|
||||
sm.sureness--
|
||||
} else {
|
||||
sm.sureness++
|
||||
}
|
||||
if sm.sureness == 0 {
|
||||
sm.color = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sm.sureness > 1 {
|
||||
t.Drop(env, 1, strconv.Itoa(sm.color))
|
||||
}
|
||||
|
||||
t.Step(env)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,38 +0,0 @@
|
|||
package actors
|
||||
|
||||
import (
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
)
|
||||
|
||||
type WoodChips struct {
|
||||
SniffDistance int
|
||||
Carrying bool
|
||||
}
|
||||
|
||||
func (a *WoodChips) Setup(env *core.Environment, t *core.Turtle) {
|
||||
//t.SetXY(150,150)
|
||||
}
|
||||
|
||||
func (a *WoodChips) Run(env *core.Environment, t *core.Turtle) {
|
||||
if a.Carrying {
|
||||
if env.HasValue(t.Pos()) {
|
||||
for {
|
||||
t.Wiggle()
|
||||
t.Step(env)
|
||||
if !env.HasValue(t.Pos()) {
|
||||
env.PutValue(t.Pos())
|
||||
a.Carrying = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if env.HasValue(t.Pos()) {
|
||||
env.TakeValue(t.Pos())
|
||||
a.Carrying = true
|
||||
t.TurnAround()
|
||||
}
|
||||
}
|
||||
t.Wiggle()
|
||||
t.Step(env)
|
||||
}
|
|
@ -5,10 +5,10 @@ import (
|
|||
)
|
||||
|
||||
type Turtle struct {
|
||||
xpos, ypos int
|
||||
heading int
|
||||
actor Actor
|
||||
width,height int
|
||||
xpos, ypos int
|
||||
heading int
|
||||
actor Actor
|
||||
width, height int
|
||||
}
|
||||
|
||||
type NilActor struct {
|
||||
|
@ -58,7 +58,7 @@ func (t *Turtle) SetXY(x, y int) {
|
|||
|
||||
if y < 0 {
|
||||
y = (t.height - 1)
|
||||
} else if y >=t.height {
|
||||
} else if y >= t.height {
|
||||
y = y % (t.height)
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ func (t *Turtle) Amount(env *Environment, distance int, pheromone string) float3
|
|||
as0 := env.SniffNormalized(x0, y0, pheromone)
|
||||
as := env.SniffNormalized(x, y, pheromone)
|
||||
as1 := env.SniffNormalized(x1, y1, pheromone)
|
||||
return as0+as+as1
|
||||
return as0 + as + as1
|
||||
}
|
||||
|
||||
func (t *Turtle) Near(env *Environment, distance int, threshold float32, pheromone string) bool {
|
||||
|
@ -152,7 +152,7 @@ func (t *Turtle) Near(env *Environment, distance int, threshold float32, pheromo
|
|||
as1 = 0
|
||||
}
|
||||
|
||||
if as0 == 0 && as == 0 && as1 == 0 {
|
||||
if as0 == 0 && as == 0 && as1 == 0 {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
|
|
|
@ -0,0 +1,102 @@
|
|||
package experiments
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"git.openprivacy.ca/sarah/microworlds/graphics"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"image/color"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
|
||||
var width = flag.Int("width", 300, "width of environment")
|
||||
var height = flag.Int("height", 300, "height of environment")
|
||||
var pxsize = flag.Int("pxsize", 1, "pixels per tile edge")
|
||||
var numTurtles = flag.Int("numTurtles", 5000, "number of turtles")
|
||||
|
||||
type Experiment struct {
|
||||
env *core.Environment
|
||||
turtles []*core.Turtle
|
||||
graphics *graphics.Graphics
|
||||
initializedTurtles int
|
||||
}
|
||||
|
||||
func (e *Experiment) InitializeExperiment() {
|
||||
// We don't need real randomness
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
flag.Parse()
|
||||
if *cpuprofile != "" {
|
||||
f, err := os.Create(*cpuprofile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
pprof.StartCPUProfile(f)
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
e.env = core.NewEnvironment(*width, *height)
|
||||
e.turtles = make([]*core.Turtle, *numTurtles)
|
||||
e.graphics = graphics.NewGraphics(int32(*width), int32(*height), int32(*pxsize))
|
||||
}
|
||||
|
||||
func (e *Experiment) GetNumTurtles() int {
|
||||
return (*numTurtles)
|
||||
}
|
||||
|
||||
func (e *Experiment) InitPheromone(name string, col color.Color) {
|
||||
e.env.InitPheromone(name)
|
||||
r, g, b, a := col.RGBA()
|
||||
e.graphics.ColorPheromone(name, [4]uint8{uint8(r), uint8(g), uint8(b), uint8(a)})
|
||||
}
|
||||
|
||||
func (e *Experiment) InitEnvironment(f func(environment *core.Environment)) {
|
||||
f(e.env)
|
||||
}
|
||||
|
||||
func (e *Experiment) InitNTurtles(f func() core.Actor, num int) {
|
||||
for i := e.initializedTurtles; i < e.initializedTurtles+num; i++ {
|
||||
e.turtles[i] = core.NewTurtle(e.env, f())
|
||||
}
|
||||
e.initializedTurtles += num
|
||||
}
|
||||
|
||||
func (e *Experiment) InitTurtles(f func() core.Actor) {
|
||||
e.InitNTurtles(f, (*numTurtles))
|
||||
}
|
||||
|
||||
func (e *Experiment) Run() {
|
||||
wait := sync.WaitGroup{}
|
||||
|
||||
running := true
|
||||
wait.Add(1)
|
||||
go func() {
|
||||
for running {
|
||||
e.graphics.Render(e.env, e.turtles)
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
|
||||
wait.Add(1)
|
||||
for running {
|
||||
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
||||
switch event.(type) {
|
||||
case *sdl.QuitEvent:
|
||||
running = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
wait.Wait()
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"git.openprivacy.ca/sarah/microworlds/experiments"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var prob = flag.Float64("distribution", .51, "drives the probability of color assignment of turtles in consensus models, closer to .5 results in more even assignment, closer to 0 or 1 biases in favor of a color.")
|
||||
var byzantineTurtles = flag.Int("byzantineTurtles", 50, "in consensus simlulations, the number of turtles who will always vote 2")
|
||||
|
||||
type Isolate struct {
|
||||
color int
|
||||
Probability float64
|
||||
sureness float32
|
||||
Byztantine bool
|
||||
}
|
||||
|
||||
func (sm *Isolate) Setup(env *core.Environment, t *core.Turtle) {
|
||||
num := rand.Intn(100)
|
||||
if num >= int(sm.Probability*100.0) {
|
||||
sm.color = 2
|
||||
} else {
|
||||
sm.color = 1
|
||||
}
|
||||
sm.sureness = 2
|
||||
}
|
||||
|
||||
func (sm *Isolate) Run(env *core.Environment, t *core.Turtle) {
|
||||
if sm.Byztantine {
|
||||
t.Wiggle()
|
||||
t.FollowGradient(env, 10, 0, "2")
|
||||
t.Drop(env, 1, "2")
|
||||
t.Step(env)
|
||||
} else {
|
||||
t.Wiggle()
|
||||
am1 := t.Amount(env, 1, "1")
|
||||
am2 := t.Amount(env, 1, "2")
|
||||
|
||||
if am1 > sm.sureness || am2 > sm.sureness {
|
||||
if am1 > am2 {
|
||||
if sm.color == 2 {
|
||||
sm.sureness--
|
||||
} else {
|
||||
sm.sureness++
|
||||
}
|
||||
if sm.sureness == 0 {
|
||||
sm.color = 1
|
||||
}
|
||||
} else if am2 > am1 {
|
||||
if sm.color == 1 {
|
||||
sm.sureness--
|
||||
} else {
|
||||
sm.sureness++
|
||||
}
|
||||
if sm.sureness == 0 {
|
||||
sm.color = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sm.sureness > 1 {
|
||||
t.Drop(env, 1, strconv.Itoa(sm.color))
|
||||
}
|
||||
|
||||
t.Step(env)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
experiment := new(experiments.Experiment)
|
||||
experiment.InitializeExperiment()
|
||||
honestTurtles := experiment.GetNumTurtles() - (*byzantineTurtles)
|
||||
experiment.InitNTurtles(func() core.Actor {
|
||||
sm := new(Isolate)
|
||||
sm.Probability = *prob
|
||||
return sm
|
||||
}, honestTurtles)
|
||||
experiment.InitNTurtles(func() core.Actor {
|
||||
sm := new(Isolate)
|
||||
sm.Probability = *prob
|
||||
sm.Byztantine = true
|
||||
return sm
|
||||
}, (*byzantineTurtles))
|
||||
experiment.InitPheromone("1", color.RGBA{0x00, 0xFF, 0x00, 0x00})
|
||||
experiment.InitPheromone("2", color.RGBA{0xFF, 0x00, 0xFF, 0x00})
|
||||
experiment.Run()
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"git.openprivacy.ca/sarah/microworlds/experiments"
|
||||
"image/color"
|
||||
)
|
||||
|
||||
var sniffDistance = flag.Int("sniffDistance", 5, "the distance a turtle can detect pheromone levels from")
|
||||
|
||||
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")
|
||||
}
|
||||
|
||||
func main() {
|
||||
experiment := new(experiments.Experiment)
|
||||
experiment.InitializeExperiment()
|
||||
experiment.InitTurtles(func() core.Actor {
|
||||
sm := new(MazeGeneration)
|
||||
sm.SniffDistance = *sniffDistance
|
||||
return sm
|
||||
})
|
||||
experiment.InitPheromone("trail", color.RGBA{0x81, 0x00, 0x81, 0x00})
|
||||
experiment.Run()
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"git.openprivacy.ca/sarah/microworlds/experiments"
|
||||
"image/color"
|
||||
)
|
||||
|
||||
var sniffDistance = flag.Int("sniffDistance", 3, "the distance a turtle can detect pheromone levels from")
|
||||
|
||||
type SlimeMold struct {
|
||||
SniffDistance int
|
||||
}
|
||||
|
||||
func (sm *SlimeMold) Setup(env *core.Environment, t *core.Turtle) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
func (sm *SlimeMold) Run(env *core.Environment, t *core.Turtle) {
|
||||
t.Wiggle()
|
||||
t.FollowGradient(env, sm.SniffDistance, 2, "trail")
|
||||
t.Step(env)
|
||||
t.Drop(env, 1, "trail")
|
||||
}
|
||||
|
||||
func main() {
|
||||
experiment := new(experiments.Experiment)
|
||||
experiment.InitializeExperiment()
|
||||
experiment.InitTurtles(func() core.Actor {
|
||||
sm := new(SlimeMold)
|
||||
sm.SniffDistance = *sniffDistance
|
||||
return sm
|
||||
})
|
||||
experiment.InitPheromone("trail", color.RGBA{0x80, 0xFF, 0x00, 0x00})
|
||||
experiment.Run()
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"git.openprivacy.ca/sarah/microworlds/experiments"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var prob = flag.Float64("distribution", .51, "drives the probability of color assignment of turtles in consensus models, closer to .5 results in more even assignment, closer to 0 or 1 biases in favor of a color.")
|
||||
|
||||
type Slush struct {
|
||||
color int
|
||||
Probability float64
|
||||
}
|
||||
|
||||
func NewSlushTurtle() core.Actor {
|
||||
turtle := new(Slush)
|
||||
turtle.Probability = *prob
|
||||
return turtle
|
||||
}
|
||||
|
||||
func (sm *Slush) Setup(env *core.Environment, t *core.Turtle) {
|
||||
num := rand.Intn(100)
|
||||
if num >= int(sm.Probability*100.0) {
|
||||
sm.color = 2
|
||||
} else {
|
||||
sm.color = 1
|
||||
}
|
||||
}
|
||||
|
||||
func (sm *Slush) Run(env *core.Environment, t *core.Turtle) {
|
||||
t.Wiggle()
|
||||
am1 := t.Amount(env, 1, "1")
|
||||
am2 := t.Amount(env, 1, "2")
|
||||
|
||||
t.Drop(env, 1, strconv.Itoa(sm.color))
|
||||
|
||||
if am1 > 3 || am2 > 3 {
|
||||
if am1 > am2 {
|
||||
sm.color = 1
|
||||
} else if am2 > am1 {
|
||||
sm.color = 2
|
||||
}
|
||||
}
|
||||
t.Step(env)
|
||||
}
|
||||
|
||||
func main() {
|
||||
experiment := new(experiments.Experiment)
|
||||
experiment.InitializeExperiment()
|
||||
experiment.InitTurtles(NewSlushTurtle)
|
||||
experiment.InitPheromone("1", color.RGBA{0x80, 0xFF, 0x00, 0x00})
|
||||
experiment.InitPheromone("2", color.RGBA{0xFF, 0x00, 0xFF, 0x00})
|
||||
experiment.Run()
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"git.openprivacy.ca/sarah/microworlds/experiments"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
var prob = flag.Float64("distribution", .51, "drives the probability of color assignment of turtles in consensus models, closer to .5 results in more even assignment, closer to 0 or 1 biases in favor of a color.")
|
||||
var byzantineTurtles = flag.Int("byzantineTurtles", 50, "in consensus simlulations, the number of turtles who will always vote 2")
|
||||
|
||||
type Snowball struct {
|
||||
color int
|
||||
Probability float64
|
||||
sureness float32
|
||||
Byztantine bool
|
||||
}
|
||||
|
||||
func (sm *Snowball) Setup(env *core.Environment, t *core.Turtle) {
|
||||
num := rand.Intn(100)
|
||||
if num >= int(sm.Probability*100.0) {
|
||||
sm.color = 2
|
||||
} else {
|
||||
sm.color = 1
|
||||
}
|
||||
sm.sureness = 2
|
||||
}
|
||||
|
||||
func (sm *Snowball) Run(env *core.Environment, t *core.Turtle) {
|
||||
if sm.Byztantine {
|
||||
t.Wiggle()
|
||||
t.Drop(env, 1, "2")
|
||||
} else {
|
||||
t.Wiggle()
|
||||
am1 := t.Amount(env, 1, "1")
|
||||
am2 := t.Amount(env, 1, "2")
|
||||
|
||||
if am1 > sm.sureness || am2 > sm.sureness {
|
||||
if am1 > am2 {
|
||||
if sm.color == 2 {
|
||||
sm.sureness--
|
||||
} else {
|
||||
sm.sureness++
|
||||
}
|
||||
if sm.sureness == 0 {
|
||||
sm.color = 1
|
||||
}
|
||||
} else if am2 > am1 {
|
||||
if sm.color == 1 {
|
||||
sm.sureness--
|
||||
} else {
|
||||
sm.sureness++
|
||||
}
|
||||
if sm.sureness == 0 {
|
||||
sm.color = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sm.sureness > 1 {
|
||||
t.Drop(env, 1, strconv.Itoa(sm.color))
|
||||
}
|
||||
|
||||
t.Step(env)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
experiment := new(experiments.Experiment)
|
||||
experiment.InitializeExperiment()
|
||||
honestTurtles := experiment.GetNumTurtles() - (*byzantineTurtles)
|
||||
experiment.InitNTurtles(func() core.Actor {
|
||||
sm := new(Snowball)
|
||||
sm.Probability = *prob
|
||||
return sm
|
||||
}, honestTurtles)
|
||||
experiment.InitNTurtles(func() core.Actor {
|
||||
sm := new(Snowball)
|
||||
sm.Probability = *prob
|
||||
sm.Byztantine = true
|
||||
return sm
|
||||
}, (*byzantineTurtles))
|
||||
experiment.InitPheromone("1", color.RGBA{0x00, 0xFF, 0x00, 0x00})
|
||||
experiment.InitPheromone("2", color.RGBA{0xFF, 0x00, 0xFF, 0x00})
|
||||
experiment.Run()
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"git.openprivacy.ca/sarah/microworlds/experiments"
|
||||
"image/color"
|
||||
)
|
||||
|
||||
var sniffDistance = flag.Int("sniffDistance", 3, "the distance an ant can detect pheromone levels from")
|
||||
var dropSize = flag.Float64("dropSize", 1.0, "the amount of pheromone an ants drops")
|
||||
|
||||
type Ant struct {
|
||||
SniffDistance int
|
||||
Carrying bool
|
||||
DropSize float64
|
||||
}
|
||||
|
||||
func (a *Ant) Setup(env *core.Environment, t *core.Turtle) {
|
||||
}
|
||||
|
||||
func (a *Ant) Run(env *core.Environment, t *core.Turtle) {
|
||||
if a.Carrying == false {
|
||||
if env.HasValue(t.Pos()) {
|
||||
env.TakeValue(t.Pos())
|
||||
a.Carrying = true
|
||||
a.DropSize = 100
|
||||
t.TurnAround()
|
||||
} else {
|
||||
t.Wiggle()
|
||||
t.FollowGradient(env, a.SniffDistance, 5, "food")
|
||||
}
|
||||
t.Step(env)
|
||||
} else if a.Carrying == true {
|
||||
a.DropSize -= 0.6
|
||||
t.Drop(env, float32(a.DropSize), "food")
|
||||
t.Wiggle()
|
||||
t.Step(env)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
experiment := new(experiments.Experiment)
|
||||
experiment.InitializeExperiment()
|
||||
experiment.InitEnvironment(func(environment *core.Environment) {
|
||||
// Create 2 food piles
|
||||
for x := 100; x < 110; x++ {
|
||||
for y := 100; y < 110; y++ {
|
||||
environment.PutValue(x, y)
|
||||
}
|
||||
}
|
||||
for x := 200; x < 210; x++ {
|
||||
for y := 200; y < 210; y++ {
|
||||
environment.PutValue(x, y)
|
||||
}
|
||||
}
|
||||
})
|
||||
experiment.InitTurtles(func() core.Actor {
|
||||
sm := new(Ant)
|
||||
sm.SniffDistance = *sniffDistance
|
||||
sm.DropSize = *dropSize
|
||||
return sm
|
||||
})
|
||||
experiment.InitPheromone("food", color.RGBA{0x81, 0x81, 0x12, 0x00})
|
||||
experiment.Run()
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"git.openprivacy.ca/sarah/microworlds/experiments"
|
||||
"image/color"
|
||||
"math/rand"
|
||||
)
|
||||
|
||||
var sniffDistance = flag.Int("sniffDistance", 3, "the distance a turtle can detect pheromone levels from")
|
||||
var numWoodChips = flag.Int("numWoodChips", 5000, "the number of woodchips in the model")
|
||||
|
||||
type WoodChips struct {
|
||||
SniffDistance int
|
||||
Carrying bool
|
||||
}
|
||||
|
||||
func (a *WoodChips) Setup(env *core.Environment, t *core.Turtle) {
|
||||
}
|
||||
|
||||
func (a *WoodChips) Run(env *core.Environment, t *core.Turtle) {
|
||||
if a.Carrying {
|
||||
if env.HasValue(t.Pos()) {
|
||||
for {
|
||||
t.Wiggle()
|
||||
t.Step(env)
|
||||
if !env.HasValue(t.Pos()) {
|
||||
env.PutValue(t.Pos())
|
||||
a.Carrying = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if env.HasValue(t.Pos()) {
|
||||
env.TakeValue(t.Pos())
|
||||
a.Carrying = true
|
||||
t.TurnAround()
|
||||
}
|
||||
}
|
||||
t.Wiggle()
|
||||
t.Step(env)
|
||||
}
|
||||
|
||||
func main() {
|
||||
experiment := new(experiments.Experiment)
|
||||
experiment.InitializeExperiment()
|
||||
experiment.InitEnvironment(func(environment *core.Environment) {
|
||||
for x := 0; x < *numWoodChips; x++ {
|
||||
environment.PutValue(rand.Intn(environment.Width()), rand.Intn(environment.Height()))
|
||||
}
|
||||
|
||||
for x := 200; x < 210; x++ {
|
||||
for y := 200; y < 210; y++ {
|
||||
environment.PutValue(x, y)
|
||||
}
|
||||
}
|
||||
})
|
||||
experiment.InitTurtles(func() core.Actor {
|
||||
sm := new(WoodChips)
|
||||
sm.SniffDistance = *sniffDistance
|
||||
return sm
|
||||
})
|
||||
experiment.InitPheromone("trail", color.RGBA{0x80, 0xFF, 0x00, 0x00})
|
||||
experiment.Run()
|
||||
}
|
|
@ -7,16 +7,15 @@ import (
|
|||
"math"
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
//"strconv"
|
||||
)
|
||||
|
||||
type Graphics struct {
|
||||
window *sdl.Window
|
||||
renderer *sdl.Renderer
|
||||
window *sdl.Window
|
||||
renderer *sdl.Renderer
|
||||
width, height, pxsize int32
|
||||
t int
|
||||
colorMap map[string][4]uint8
|
||||
t int
|
||||
colorMap map[string][4]uint8
|
||||
}
|
||||
|
||||
func NewGraphics(width, height, pxsize int32) *Graphics {
|
||||
|
@ -25,7 +24,7 @@ func NewGraphics(width, height, pxsize int32) *Graphics {
|
|||
graphics.height = height
|
||||
graphics.pxsize = pxsize
|
||||
window, err := sdl.CreateWindow("Microworlds", sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
|
||||
width * pxsize, height * pxsize, sdl.WINDOW_SHOWN)
|
||||
width*pxsize, height*pxsize, sdl.WINDOW_SHOWN)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -65,20 +64,20 @@ func (g *Graphics) Render(env *core.Environment, turtles []*core.Turtle) {
|
|||
amount := math.Min(float64(env.Sniff(name, x, y)), 255)
|
||||
|
||||
if amount > 2 {
|
||||
amount = 2
|
||||
amount = 2
|
||||
}
|
||||
|
||||
if amount > 0 {
|
||||
scaledamountRed := uint8(float64(color[0]) * (amount/2))
|
||||
scaledamountGreen := uint8(float64(color[1]) * (amount/2))
|
||||
scaledamountBlue := uint8(float64(color[2]) * (amount/2))
|
||||
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.SetDrawColor(uint8(scaledamountRedTotal/len(g.colorMap)), uint8(scaledamountGreenTotal/len(g.colorMap)), uint8(scaledamountBlueTotal/len(g.colorMap)), uint8(0xF0))
|
||||
g.DrawTileColor(int32(x), int32(y))
|
||||
|
||||
if env.HasValue(x, y) {
|
||||
|
|
176
main.go
176
main.go
|
@ -1,176 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"git.openprivacy.ca/sarah/microworlds/actors"
|
||||
"git.openprivacy.ca/sarah/microworlds/core"
|
||||
"git.openprivacy.ca/sarah/microworlds/graphics"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"log"
|
||||
"math/rand"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var cpuprofile = flag.String("cpuprofile", "", "write cpu profile to file")
|
||||
|
||||
var model = flag.String("model", "slime", "slimemold|swarm|woodchips")
|
||||
|
||||
var width = flag.Int("width", 300, "width of environment")
|
||||
var height = flag.Int("height", 300, "height of environment")
|
||||
var pxsize = flag.Int("pxsize", 1, "pixels per tile edge")
|
||||
var numTurtles = flag.Int("numTurtles", 5000, "number of turtles")
|
||||
var byzantineTurtles = flag.Int("byzantineTurtles", 50,"in consensus simlulations, the number of turtles who will always vote 2")
|
||||
var prob = flag.Float64("distribution", .51, "drives the probability of color assignment of turtles in consensus models, closer to .5 results in more even assignment, closer to 0 or 1 biases in favor of a color.")
|
||||
|
||||
func main() {
|
||||
|
||||
// We don't need real randomness
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
flag.Parse()
|
||||
if *cpuprofile != "" {
|
||||
f, err := os.Create(*cpuprofile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
pprof.StartCPUProfile(f)
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
if err := sdl.Init(sdl.INIT_EVERYTHING); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer sdl.Quit()
|
||||
|
||||
env := core.NewEnvironment(*width, *height)
|
||||
turtles := make([]*core.Turtle, *numTurtles)
|
||||
g := graphics.NewGraphics(int32(*width), int32(*height), int32(*pxsize))
|
||||
|
||||
switch *model {
|
||||
|
||||
case "swarm":
|
||||
// Create 2 food blocks
|
||||
for x := 100; x < 110; x++ {
|
||||
for y := 100; y < 110; y++ {
|
||||
env.PutValue(x, y)
|
||||
}
|
||||
}
|
||||
for x := 200; x < 210; x++ {
|
||||
for y := 200; y < 210; y++ {
|
||||
env.PutValue(x, y)
|
||||
}
|
||||
}
|
||||
for i := 0; i < *numTurtles; i++ {
|
||||
turtles[i] = core.NewTurtle(env, &actors.Ant{SniffDistance: 3, Carrying: false})
|
||||
}
|
||||
env.InitPheromone("food")
|
||||
g.ColorPheromone("food", [4]uint8{0x81, 0x81, 0x12, 0x00})
|
||||
case "woodchips":
|
||||
for x := 0; x < *numTurtles; x++ {
|
||||
env.PutValue(rand.Intn(*width), rand.Intn(*height))
|
||||
}
|
||||
|
||||
for x := 200; x < 210; x++ {
|
||||
for y := 200; y < 210; y++ {
|
||||
env.PutValue(x, y)
|
||||
}
|
||||
}
|
||||
for i := 0; i < *numTurtles; i++ {
|
||||
turtles[i] = core.NewTurtle(env, &actors.WoodChips{SniffDistance: 20, Carrying: false})
|
||||
}
|
||||
case "slimemold":
|
||||
for i := 0; i < *numTurtles; i++ {
|
||||
turtles[i] = core.NewTurtle(env, &actors.SlimeMold{SniffDistance: 5})
|
||||
}
|
||||
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{Probability:float32(*prob)})
|
||||
}
|
||||
env.InitPheromone("1")
|
||||
env.InitPheromone("2")
|
||||
g.ColorPheromone("1", [4]uint8{0x80, 0xFF, 0x00, 0x00})
|
||||
g.ColorPheromone("2", [4]uint8{0xFF, 0, 0xFF, 0x00})
|
||||
case "snowball":
|
||||
for i := 0; i < *numTurtles; i++ {
|
||||
turtles[i] = core.NewTurtle(env, &actors.Snowball{Probability:float32(*prob)})
|
||||
}
|
||||
env.InitPheromone("1")
|
||||
env.InitPheromone("2")
|
||||
g.ColorPheromone("1", [4]uint8{0x00, 0xFF, 0x80, 0x00})
|
||||
g.ColorPheromone("2", [4]uint8{0xFF, 0x80, 0x00, 0x00})
|
||||
case "snowball-byzantine":
|
||||
honestTurtles := (*numTurtles)-(*byzantineTurtles)
|
||||
for i := 0; i < honestTurtles; i++ {
|
||||
turtles[i] = core.NewTurtle(env, &actors.Snowball{Probability:float32(*prob)})
|
||||
}
|
||||
for i := honestTurtles; i < honestTurtles+(*byzantineTurtles); i++ {
|
||||
turtles[i] = core.NewTurtle(env, &actors.Snowball{Probability:float32(*prob), Byztantine:true})
|
||||
}
|
||||
env.InitPheromone("1")
|
||||
env.InitPheromone("2")
|
||||
g.ColorPheromone("1", [4]uint8{0x00, 0xFF, 0x80, 0x00})
|
||||
g.ColorPheromone("2", [4]uint8{0xFF, 0x00, 0xa5, 0x00})
|
||||
case "isolate":
|
||||
honestTurtles := (*numTurtles)-(*byzantineTurtles)
|
||||
for i := 0; i < honestTurtles; i++ {
|
||||
turtles[i] = core.NewTurtle(env, &actors.Isolate{Probability:float32(*prob)})
|
||||
}
|
||||
for i := honestTurtles; i < honestTurtles+(*byzantineTurtles); i++ {
|
||||
turtles[i] = core.NewTurtle(env, &actors.Isolate{Probability:float32(*prob), Byztantine:true})
|
||||
}
|
||||
env.InitPheromone("1")
|
||||
env.InitPheromone("2")
|
||||
g.ColorPheromone("1", [4]uint8{0x00, 0xFF, 0x80, 0x00})
|
||||
g.ColorPheromone("2", [4]uint8{0xFF, 0x00, 0xa5, 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++ {
|
||||
turtles[i] = core.NewTurtle(env, &actors.SlimeMold{SniffDistance: 20})
|
||||
}
|
||||
env.InitPheromone("trail")
|
||||
g.ColorPheromone("trail", [4]uint8{0x81, 0, 0x81, 0x00})
|
||||
}
|
||||
|
||||
running := true
|
||||
wait := sync.WaitGroup{}
|
||||
|
||||
wait.Add(1)
|
||||
go func() {
|
||||
for running {
|
||||
g.Render(env, turtles)
|
||||
}
|
||||
wait.Done()
|
||||
}()
|
||||
|
||||
wait.Add(1)
|
||||
for running {
|
||||
for event := sdl.PollEvent(); event != nil; event = sdl.PollEvent() {
|
||||
switch event.(type) {
|
||||
case *sdl.QuitEvent:
|
||||
running = false
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
wait.Done()
|
||||
wait.Wait()
|
||||
}
|
Loading…
Reference in New Issue