Skip to content

Instantly share code, notes, and snippets.

@abachman
Created September 17, 2011 21:20
Show Gist options
  • Save abachman/1224386 to your computer and use it in GitHub Desktop.
Save abachman/1224386 to your computer and use it in GitHub Desktop.
conway.coffee
class World
constructor: (@cells, @display) ->
@height = @cells.length
@width = @cells[0].length
@neighbor_matrix = [
[ [-1, -1], [0, -1], [1, -1]]
[ [-1, 0] , [1, 0] ]
[ [-1, 1], [0, 1], [1, 1] ]
]
@render()
next: ->
@update()
@render()
update: ->
_new_cells = []
for row, y in @cells
_new_cells.push []
for col, x in row
c = @neighbor_count(x, y)
if col is 1
if c is 2 or c is 3
col = 1
else
col = 0
else if col is 0
if c is 3
col = 1
_new_cells[y].push col
@cells = _new_cells
render: ->
$(@display).empty()
out = []
for row, y in @cells
out.push "<tr>"
for cell, x in row
out.push "<td data-point='#{x},#{y}'
class='#{@state(cell)}'
id='#{x}-#{y}'>&nbsp;</td>"
out.push '</tr>'
$(@display).html out.join()
state: (c) ->
if c == 0 then 'dead' else ''
neighbor_count: (x, y) ->
living = 0
self = this
_.each @neighbor_matrix, (row) ->
_.each row, (coords) ->
nx = coords[0] + x
ny = coords[1] + y
if nx >= 0 && ny >= 0 && nx < self.width && ny < self.height
living += self.cells[ny][nx]
living
toggle: (coords) ->
{x, y} = coords
@cells[y][x] = if @cells[y][x] is 0 then 1 else 0
# add a pattern to the screen
set: (pattern, point, rotation) ->
self = this
_.each pattern, (row, py) =>
_.each row, (value, px) =>
nx = point.x + px
ny = point.y + py
if nx >= 0 && ny >= 0 && nx < self.width && ny < self.height
self.cells[ny][nx] = value
if value == 0
$('#' + nx + '-' + ny).addClass('dead')
else
$('#' + nx + '-' + ny).removeClass('dead')
$ =>
map = []
y = 0
x = 0
size = 30
while y < size
map.push []
while x < size + 30
map[y].push 0
x += 1
y += 1
x = 0
world = new World map, $('#conway')
a_glider = [
[0, 0, 1]
[1, 0, 1]
[0, 1, 1]
]
bind_click = =>
$('#conway td').bind 'click', ->
$(this).toggleClass('dead')
point = $(this).data('point').split(',')
point =
x: parseInt point[0]
y: parseInt point[1]
if glider_mode
console.log 'glider'
world.set a_glider, point, 0
else
console.log 'point'
world.toggle point
unbind_click = =>
$('#conway td').unbind 'click'
runner = null
running = false
glider_mode = false
bind_click()
$(document).bind 'keydown', (event) =>
if event.keyCode is 32
$('#modal').hide();
$('#paused').toggleClass('hidden');
event.preventDefault();
if running
clearInterval runner
running = false
bind_click()
else
unbind_click()
runner = setInterval((-> world.next()), 50)
running = true
else if event.keyCode is 71
# little 'g'
glider_mode = !glider_mode
$('#glider').toggleClass('hidden')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment