Skip to content

Instantly share code, notes, and snippets.

@joejag
Created October 28, 2012 19:27
Show Gist options
  • Save joejag/3969578 to your computer and use it in GitHub Desktop.
Save joejag/3969578 to your computer and use it in GitHub Desktop.
Conways Game of Life in CoffeeScript
#
# Utility methods: Uses Underscore.js
#
flatten_nested_array = (array) -> _.flatten(array, true) # flattens to one level of nesting
includes = (target, coll) -> _.any(coll, (item) -> _.isEqual(item, target)) # allows for searching for arrays
frequencies = (coll) -> _.countBy(coll, _.identity) # return a map of how many times each element appears in a given list
# Javascript only supports strings as keys for associative arrays. This converts a "1,1" into [1,1]
key_to_array = (string) ->
splitted = string.split(',')
[parseInt(splitted[0]), parseInt(splitted[1])]
#
# Conway's Game of Life
#
neighbours_of = ([x, y]) ->
[[x-1, y+1], [x, y+1], [x+1, y+1],
[x-1, y ], [x+1, y ],
[x-1, y-1], [x, y-1], [x+1, y-1]]
neighbour_frequencies = (world) ->
all_neighbours_of_live_cells = (neighbours_of(cell) for cell in world)
frequencies(flatten_nested_array(all_neighbours_of_live_cells))
survives = (num_of_neighbours, alive) ->
return yes if alive and (num_of_neighbours == 2 or num_of_neighbours == 3)
return yes if not alive and num_of_neighbours == 3
no
is_alive = (cell, world) ->
includes(key_to_array(cell), world)
evolve = (world) ->
(key_to_array(cell) for cell, count of neighbour_frequencies(world) when survives(count, is_alive(cell, world)))
game_loop = (world, times_to_evolve, listener) ->
for [1..times_to_evolve]
world = evolve(world)
listener(world)
# world is a set of live cells
world = [[0, 1], [1, 1], [2, 1]]
game_loop(world, 5, (new_world) ->
console.log (cell.toString() for cell in new_world))
# prints
# ["1,2", "1,1", "1,0"]
# ["0,1", "1,1", "2,1"]
# ["1,2", "1,1", "1,0"]
# ["0,1", "1,1", "2,1"]
# ["1,2", "1,1", "1,0"]
<script src="http://code.jquery.com/jquery-1.8.2.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="game_of_life.js"></script>
@latentflip
Copy link

Why not just

for candidate_cell in all_neighbouring_cells frequencies_found[candidate_cell] ||= 0 frequencies_found[candidate_cell]++

@latentflip
Copy link

^ except with not broken indentation ;)

@joejag
Copy link
Author

joejag commented Oct 28, 2012

Very nice. I've changed the frequencies method accordingly!

@joejag
Copy link
Author

joejag commented Oct 28, 2012

I've reshaped frequencies into a utility function, which makes it clearer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment