Repository navigation
Expand file tree
/
Copy pathlife.html
More file actions
127 lines (104 loc) · 3.53 KB
/
Copy pathlife.html
File metadata and controls
127 lines (104 loc) · 3.53 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
<html>
<head>
<title>Life Model</title>
<script src="../lib/agentscript.js"></script>
<script src="../tools/dat.gui.min.js"></script>
<script src="../lib/as.dat.gui.js"></script>
<script src="../tools/coffee-script.js"></script>
<script type="text/coffeescript">
class LifeModel extends ABM.Model
startup: ->
@livingColor = [255, 255, 255]
@deadColor = [0, 0, 0]
setup: ->
for p in @patches
if Math.random() < 0.3
@birth(p)
else
@death(p)
step: ->
# Alternate between updating each patch's living neighbor count,
# and changing the `living` state variable of each patch.
# Since both models are triggered by a requestAnimationFrame callback
# in an ABM.Animator, the models should be guaranteed to run in lock-step.
if @anim.ticks % 2 is 1
@countLivingNeighbors()
else
@enactBirthsAndDeaths()
countLivingNeighbors: () ->
for p in @patches
if @linkEnabled
# If the models are "linked", a patch's neighbors exist
# only in the model to which it is linked.
linkedPatch = @linkedModel.patches.patch(p.x, p.y)
else
linkedPatch = p
p.liveNeighbors = linkedPatch.n.with((p) -> p.living).length
enactBirthsAndDeaths: () ->
for p in @patches
# A patch will go from being dead to being alive
# if it has exactly three living neighbors
if p.liveNeighbors is 3
@birth(p)
else
# A living patch will stay living only if it
# has exactly two living neighbors
unless p.liveNeighbors is 2
@death(p)
birth: (p) ->
p.living = true
p.color = @livingColor
death: (p) ->
p.living = false
p.color = @deadColor
linkModel: (model) ->
@linkedModel = model
@linkEnabled = true
setupBothModels: () ->
@reset()
@linkedModel.reset()
@start()
@linkedModel.start()
toggleLink: () ->
@linkEnabled = @linkedModel.linkEnabled = not @linkEnabled
modelOpts = { size: 8, minX: 0, maxX: 50, minY: 0, maxY: 50 }
modelOpts.div = 'model2'
model1 = window.model1 = new LifeModel(modelOpts)
modelOpts.div = 'model1'
model2 = window.model2 = new LifeModel(modelOpts)
# make the model divs display side by side
model1.div.style.display = model2.div.style.display = 'inline-block'
model1.linkModel(model2)
model2.linkModel(model1)
model1.on 'step', () ->
ticks = model1.anim.ticks
if (ticks % 100 is 0)
console.log "model1:", model1.anim.toString()
model2.on 'draw', () ->
draws = model2.anim.draws
if (draws % 100 is 0)
console.log "model2:", model2.anim.toString()
model1.on 'setup', () ->
console.log "setup model1"
model2.on 'setup', () ->
console.log "setup model2"
window.gui1 = new ABM.DatGUI(model1, {
"setup": {
type: "button",
setter: "setupBothModels"
},
"link": {
type: "switch",
val: true,
setter: "toggleLink"
}
})
model1.start()
model2.start()
</script>
</head>
<body>
<div id="model1"></div>
<div id="model2"></div>
</body>
</html>