Skip to content

Instantly share code, notes, and snippets.

@resilience-me
Last active April 11, 2017 00:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save resilience-me/3641952b546c823489c2a00316830e50 to your computer and use it in GitHub Desktop.
Save resilience-me/3641952b546c823489c2a00316830e50 to your computer and use it in GitHub Desktop.
u = ABM.util # shortcut for ABM.util, some tools
log = (arg) -> console.log arg # log to the browser console
class ABM.TemplateModel extends ABM.Model
setup: ->
@stopTick = 200
# Transactions have random time intervals between them,
# @nextTransaction is increased with u.randomInt(5, 10) each transaction
@nextTransaction = 2
# Style the agents
@agents.setDefault "shape", "circle"
@agents.setUseSprites() # agent.strokeColor seems to need sprites
@agents.setDefault "strokeColor", u.color.black
@links.setDefault "thickness", .75 # Easier to see thinner link
@links.setDefault "color", u.color.black
@mostRecentTimestamp = {}
@maxValueX = 30
@dividendPathways = []
@taxRate = 2
# Agents can be either human or non-human
@humans = [] # In a swarm redistribution pulse, stores humans
@inHumans = [] # Used with @humans during a swarm redistribution pulse,
@isHuman = []
for i in [1...@maxValueX]
@isHuman[i] = u.randomInt(2)
@totalBasicIncome = []
@totalTransactions = 0
@totalTaxCollected = 0
# Each agent gets their own color, set by their
# position on the x-axis
@agentColors = [
u.color.blue,
u.color.chocolate,
u.color.red,
u.color.silver,
u.color.lawngreen,
u.color.orange,
u.color.wheat,
u.color.deeppink,
u.color.lavender,
u.color.turquoise,
u.color.gold,
u.color.fuchsia,
u.color.magenta,
u.color.goldenrod,
u.color.forestgreen,
u.color.moccasin,
u.color.indigo,
u.color.lightcoral,
u.color.palegoldenrod,
u.color.purple,
u.color.rosybrown,
u.color.teal,
u.color.lightyellow,
u.color.darkorchid,
u.color.brown,
u.color.coral,
u.color.burlywood,
u.color.floralwhite,
u.color.aquamarine,
u.color.hotpink,
u.color.navy ]
# The patch grid gives each agent their own y axis.
for patch in @patches.create()
# Set x axes to a different color,
# each agent has their own y axis
if patch.position.x % 2 == 0
patch.color = u.color.pink
if patch.position.x % 2 != 0
patch.color = u.color.white
step: ->
if @animator.ticks is @nextTransaction
@newTransaction()
@nextTransaction = @animator.ticks + u.randomInt(3, 6)
if @animator.ticks is @stopTick
(console.log "Stopping at stopTick: #{@animator.ticks}"; @stop())
log(@totalBasicIncome)
log("total transactions (@totalTransactions): " + @totalTransactions + " RES")
log("total taxCollected (@totalTaxCollected): " + @totalTaxCollected + " RES")
newTransaction: ->
@fromAgent
@toAgent
amount = u.randomInt(50, 1000)
@totalTransactions += amount
taxCollected = amount * @taxRate / 100
@totalTaxCollected += taxCollected
@agents.create 1, (agent) =>
@fromAgent = agent
x = u.randomInt(@maxValueX) # Positions on the x axis from 0 to 30
timestamp = @animator.ticks
agent.moveTo x: x, y: timestamp - 2
agent.color = @agentColors[x]
@agents.create 1, (agent) =>
@toAgent = agent
x = u.randomInt(@maxValueX) # Positions on the x axis from 0 to 30
if x == @fromAgent.position.x
if x == @maxValueX
x = x - 1
else x = x + 1
timestamp = @animator.ticks
agent.moveTo x: x, y: timestamp
dividendPathway =
from: @agents.length - 2
to: @agents.length - 1
amount: amount - taxCollected
timestamp: timestamp
if @dividendPathways[x] == undefined
@dividendPathways[x] = []
@dividendPathways[x].push dividendPathway
log(@dividendPathways[x])
@connect_along_Y_axis(x, @toAgent)
@links.create @fromAgent, @toAgent
@iterateThroughSwarm(@toAgent.position.x, @animator.ticks, taxCollected)
if @humans.length != 0
@doSwarm(taxCollected)
connect_along_Y_axis: (x, agent) ->
if @mostRecentTimestamp[x] > 0
index = @mostRecentTimestamp[x]
@links.create @toAgent, @agents[index]
@mostRecentTimestamp[x] = @agents.length - 1
iterateThroughSwarm: (x, timestamp, taxCollected) ->
len = @dividendPathways[x].length
for i in [0...len]
if @dividendPathways[x][i] != undefined
if @dividendPathways[x][i].timestamp < timestamp # Pathways connect chronologically
fromAgent = @dividendPathways[x][i].from
position = @agents[fromAgent].position.x
next_timestamp = @dividendPathways[x][i].timestamp
if @isHuman[position] == 1
if @inHumans[position] == undefined
@humans.push position
@inHumans[position] = true
if @dividendPathways[x][i].amount > taxCollected
@dividendPathways[x][i].amount -= taxCollected
log("Pathway decayed with: " + taxCollected + " pathway remains: " + @dividendPathways[x][i].amount)
else
toAgent = @dividendPathways[x][i].to
@dividendPathways[x].splice(i, 1)
@agents[toAgent].hidden = true
@agents[fromAgent].hidden = true
log("Pathway removed at position x: " + position + ", y: " + timestamp)
if @dividendPathways[position] != undefined
@iterateThroughSwarm(position, next_timestamp, taxCollected)
doSwarm:(taxCollected) ->
share = taxCollected / @humans.length
len = @humans.length
log("Humans in swarm redistribution pulse (@humans.length): " + len)
log("Share of tax given out as basic income: " + share + " RES")
for i in [0...len]
position = @humans[i]
if @totalBasicIncome[position] == undefined
@totalBasicIncome[position] = 0
@totalBasicIncome[position] += share
log("Total basic income (@totalBasicIncome) for agent on position x: " + position + ", " + @totalBasicIncome[position] + " RES")
@inHumans[position] = undefined
@humans = []
window.model = new ABM.TemplateModel {
div: "world",
patchSize: 13,
mapSize: 32,
isTorus: false,
min: {x: 0, y: 0}
max: {x: 30, y: 200}
}
window.model.start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment