2019-09-25 06:38:15 +00:00
package main
import (
"flag"
2019-09-30 04:52:01 +00:00
"fmt"
2019-09-25 06:38:15 +00:00
"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." )
2019-09-30 04:52:01 +00:00
var initialSureness = flag . Int ( "initialSureness" , 2 , "how sure an honest node is of their first received colour" )
2019-09-25 06:38:15 +00:00
var byzantineTurtles = flag . Int ( "byzantineTurtles" , 50 , "in consensus simlulations, the number of turtles who will always vote 2" )
2019-09-30 04:52:01 +00:00
var cleverByzantineTurtles = flag . Bool ( "cleverByzantineTurtles" , true , "byzantine turtles try to find each other" )
2019-09-25 06:38:15 +00:00
2019-10-01 19:10:48 +00:00
var alpha = flag . Float64 ( "alpha" , 0.5 , "the proportion of votes in a voting round that a color must have before it is considered a vote for that colour" )
2019-09-25 06:38:15 +00:00
type Snowball struct {
color int
Probability float64
sureness float32
Byztantine bool
2019-10-01 19:10:48 +00:00
colourCounts [ ] int
2019-09-25 06:38:15 +00:00
}
func ( sm * Snowball ) Setup ( env * core . Environment , t * core . Turtle ) {
num := rand . Intn ( 100 )
if num >= int ( sm . Probability * 100.0 ) {
sm . color = 1
2019-10-01 19:10:48 +00:00
} else {
sm . color = 0
2019-09-25 06:38:15 +00:00
}
2019-09-30 04:52:01 +00:00
sm . sureness = float32 ( * initialSureness )
2019-10-01 19:10:48 +00:00
sm . colourCounts = make ( [ ] int , 2 )
2019-09-30 04:52:01 +00:00
}
func ( sm * Snowball ) GetColor ( ) int {
return sm . color
2019-09-25 06:38:15 +00:00
}
func ( sm * Snowball ) Run ( env * core . Environment , t * core . Turtle ) {
if sm . Byztantine {
t . Wiggle ( )
2019-09-30 04:52:01 +00:00
if * cleverByzantineTurtles {
t . FollowGradient ( env , 5 , 2 , "3" )
t . Drop ( env , 1 , "3" )
}
2019-10-01 19:10:48 +00:00
sm . color = 1
2019-09-30 04:52:01 +00:00
t . SetColor ( color . RGBA { 255 , 0 , 0 , 0 } )
2019-09-25 06:38:15 +00:00
t . Drop ( env , 1 , "2" )
2019-09-30 04:52:01 +00:00
2019-09-25 06:38:15 +00:00
} else {
2019-09-30 04:52:01 +00:00
if sm . color == 1 {
t . SetColor ( color . RGBA { 0 , 255 , 0 , 0 } )
} else {
t . SetColor ( color . RGBA { 255 , 0 , 255 , 0 } )
}
2019-09-25 06:38:15 +00:00
t . Wiggle ( )
2019-09-30 04:52:01 +00:00
am1 := t . AmountAll ( env , 1 , "1" )
am2 := t . AmountAll ( env , 1 , "2" )
2019-10-01 19:10:48 +00:00
k := float32 ( am1 + am2 )
2019-09-25 06:38:15 +00:00
2019-10-01 19:10:48 +00:00
if am1 > k * float32 ( * alpha ) && am1 > am2 {
sm . colourCounts [ 0 ] ++
} else if am2 > k * 0.5 && am2 > am1 {
sm . colourCounts [ 1 ] ++
2019-09-25 06:38:15 +00:00
}
2019-10-01 19:10:48 +00:00
sm . sureness ++
if sm . colourCounts [ sm . color ] < sm . colourCounts [ ( sm . color + 1 ) % 2 ] {
sm . color = ( sm . color + 1 ) % 2
sm . sureness = 0
2019-09-25 06:38:15 +00:00
}
2019-10-01 19:10:48 +00:00
// Add a vote for our new colour if we are sure
2019-09-25 06:38:15 +00:00
if sm . sureness > 1 {
2019-10-01 19:10:48 +00:00
t . Drop ( env , 1 , strconv . Itoa ( sm . color + 1 ) )
2019-09-25 06:38:15 +00:00
}
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 } )
2019-09-30 04:52:01 +00:00
experiment . InitPheromone ( "3" , color . RGBA { 0xFF , 0x00 , 0x00 , 0x00 } )
2019-10-01 19:10:48 +00:00
fmt . Printf ( "Step, Votes for 1, Votes for 2\n" )
2019-09-30 04:52:01 +00:00
experiment . OnStep = func ( env * core . Environment , turtles [ ] * core . Turtle , step int ) {
num1 := 0
num2 := 0
env . EvaporateAndDiffuse ( 0.99 , "1" )
env . EvaporateAndDiffuse ( 0.99 , "2" )
env . EvaporateAndDiffuse ( 0.99 , "3" )
for _ , turtle := range turtles {
agent := turtle . GetActor ( ) . ( * Snowball )
2019-10-01 19:10:48 +00:00
if agent . GetColor ( ) == 0 {
2019-09-30 04:52:01 +00:00
num1 ++
} else {
num2 ++
}
}
//if step == 0 {
fmt . Printf ( "%v,%v,%v\n" , step , num1 , num2 )
//}
}
2019-09-25 06:38:15 +00:00
experiment . Run ( )
}