Last active
April 11, 2017 00:57
-
-
Save resilience-me/3641952b546c823489c2a00316830e50 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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