-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgame.js
More file actions
265 lines (237 loc) · 7.45 KB
/
Copy pathgame.js
File metadata and controls
265 lines (237 loc) · 7.45 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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
// coordinates, location and navigation
var constants = { // adjacent cells can occur horizontally, vertically or diagonally
"nw":"nw",
"n":"n",
"ne":"ne",
"e":"e",
"se":"se",
"s":"s",
"sw":"sw",
"w":"w",
"alive":"alive",
"dead":"dead"
}
var PlayField = {
// these are pixels
"extent":{ "x":-1, "y":-1 }, // the physical maximums in pixels
"max":{ "x":-1, "y":-1 }, // the logical maximums in coorindate values
"cellSize":-1 // square, so width=height
}
function nwOf(x, y) {
return { "x":x - 1, "y":y - 1 }
}
function nOf(x, y) {
return { "x":x, "y":y - 1 }
}
function neOf(x, y) {
return { "x":x + 1, "y":y - 1 }
}
function eOf(x, y) {
return { "x":x + 1, "y":y }
}
function seOf(x, y) {
return { "x":x + 1, "y":y + 1 }
}
function sOf(x, y) {
return { "x":x, "y":y + 1 }
}
function swOf(x, y) {
return { "x":x - 1, "y":y + 1 }
}
function wOf(x, y) {
return { "x":x - 1, "y":y }
}
function oppositeOf(direction) {
switch (direction) {
case constants.nw:
return constants.se
break
case constants.n:
return constants.s
break
case constants.ne:
return constants.sw
break
case constants.e:
return constants.w
break
case constants.se:
return constants.nw
break
case constants.s:
return constants.n
break
case constants.sw:
return constants.ne
break
case constants.w:
return constants.e
break
default: throw { name:'CoordinateException', message:'\"' + direction + '\" is not a valid direction.' }
}
}
function findCell(cells, x, y) {
for (var i = 0, j = cells.length; i < j; ++i) {
if (x == cells[i].x && y == cells[i].y)
return cells[i]
}
return null
}
// cells
var Cell = function(x, y) {
if ('undefined' == x || isNaN(x) || 'undefined' == y || isNaN(y))
throw { name:'CellException', message:'invalid coordinates' }
this.x = x
this.y = y
this.state = constants.alive
this.neighbors = [] // no neighboring cells by default
this.neighbors.length = 0
}
Cell.prototype.addNeighbor = function(position, cell) {
if (constants.nw != position &&
constants.n != position &&
constants.ne != position &&
constants.e != position &&
constants.se != position &&
constants.s != position &&
constants.sw != position &&
constants.w != position)
throw { name:'CoordinateException', message:'\"' + position + '\" is not a valid direction.' }
if (constants.alive != cell.state && constants.dead != cell.state)
throw { name:'CellException', message:'invalid cell state' }
if ('undefined' == typeof this.neighbors[position])
this.neighbors.length++
this.neighbors[position] = cell
} // addNeighbor
Cell.prototype.createNeighbor = function(position) {
var cell = null
if (constants.nw != position &&
constants.n != position &&
constants.ne != position &&
constants.e != position &&
constants.se != position &&
constants.sw != position &&
constants.w)
throw { name:'CoordinateException', message:'\"' + direction + '\" is not a valid direction.' }
cell = new Cell(position.x, position.y)
if (constants.alive != cell.state)
throw { name:'CellException', message:'Dead cell created.' }
try {
this.addNeighbor(position, cell)
}
catch(CellException) {
console.error(CellException.message)
}
return cell
} // createNeighbors
Cell.prototype.findLiveNeighbors = function(cells) {
this.neighbors = []
if (1 > cells.length) return 0
var lookWhere = [ constants.nw, constants.n, constants.ne, constants.e, constants.se,
constants.s, constants.sw, constants.w ]
for (there in lookWhere) {
var whereAt
switch (lookWhere[there]) {
case constants.nw:
whereAt = nwOf(this.x, this.y)
break
case constants.n:
whereAt = nOf(this.x, this.y)
break
case constants.ne:
whereAt = neOf(this.x, this.y)
break
case constants.e:
whereAt = eOf(this.x, this.y)
break
case constants.se:
whereAt = seOf(this.x, this.y)
break
case constants.s:
whereAt = sOf(this.x, this.y)
break
case constants.sw:
whereAt = swOf(this.x, this.y)
break
case constants.w:
whereAt = wOf(this.x, this.y)
break
} // switch
var found = findCell(cells, whereAt.x, whereAt.y)
if (null == found) continue
if (constants.dead == found.state) continue
try {
this.addNeighbor(lookWhere[there], found)
if (constants.alive == this.state)
found.addNeighbor(oppositeOf(lookWhere[there]), this)
}
catch(CoordinateException) {
console.error(CoordinateException.message)
}
} // for: there
if (8 < this.neighbors.length)
throw { name:'CellException', message:'too many neighbors' }
return this.neighbors.length
} // findLiveNeighbors
var Pattern = function(whereAt, template) {
if ('object' != typeof whereAt || 'object' != typeof template)
return null
this.cells = [] // none in this pattern by default
this.name = template.name
for (var c in template.coords)
this.cells.push(new Cell(template.coords[c].x + whereAt.x, template.coords[c].y + whereAt.y))
}
// transitions
var transitions = []
var fewerThanTwo = function(cell) {
if (constants.alive == cell.state && 2 > cell.neighbors.length) {
cell.state = constants.dead // dies by starvation
return cell
}
return null
}
var twoOrThree = function(cell) {
if (constants.alive == cell.state && (2 == cell.neighbors.length || 3 == cell.neighbors.length)) {
cell.state = constants.alive // survives to next generation
return cell
}
return null
}
var moreThanThree = function(cell) {
if (constants.alive == cell.state && 3 < cell.neighbors.length) {
cell.state = constants.dead // dies by overcrowding
return cell
}
return null
}
var exactlyThree = function(cell) {
if (constants.dead == cell.state && 3 == cell.neighbors.length) {
cell.state = constants.alive // halleluiah! born again
return cell
}
return null
}
transitions.push(fewerThanTwo)
transitions.push(twoOrThree)
transitions.push(moreThanThree)
transitions.push(exactlyThree)
// miscellaneous
/**
* Code by Sean McManus http://www.sean.co.uk/a/webdesign/javascriptdelay.shtm
*/
function getClockTime()
{
var now = new Date()
var hour = now.getHours()
var minute = now.getMinutes()
var second = now.getSeconds()
var ap = "AM"
if (hour > 11) { ap = "PM" }
if (hour > 12) { hour = hour - 12 }
if (hour == 0) { hour = 12 }
if (hour < 10) { hour = "0" + hour }
if (minute < 10) { minute = "0" + minute }
if (second < 10) { second = "0" + second }
var timeString = hour + ':' + minute + ':' + second + " " + ap
return timeString
} // function getClockTime()