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)
|
|
||||||
}
|
|
|
@ -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,7 +7,6 @@ import (
|
||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
//"strconv"
|
//"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
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