-
-
Save vendethiel/5518683 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
/** | |
* Conway's Game of Life, in LiveScript | |
* ==================================== | |
* | |
* Conway's Game of Life is a cellular automaton, published by John H Conway | |
* in 1970, fulfilling the design principles but greatly simplifying the | |
* research of von Neumann, into a hypothetical machine that could build | |
* copies of itself. It is a zero-player game, meaning there is no input, and | |
* the game will progress on its own with a 'seed', or configuration, to | |
* begin with. | |
* | |
* As a computer simulation, Life (as it will be herein abbreviated) has had | |
* phenomenal cultural interest across all different fields; in my usage here, | |
* I am implementing a familiar objective pattern for Life in different | |
* languages, and in as idiomatic a structure and style as I can, in that | |
* language. | |
*/ | |
class CellState | |
(@_state) -> | |
@LIVE = new this true | |
@DEAD = new this false | |
class Cell | |
-> @_state = CellState.DEAD | |
get-state: -> @_state | |
set-state: (@_state) -> | |
class FlatVector | |
(@x, @y) -> | |
plus: (v) -> new FlatVector @x + v.x, @y + v.y | |
to-id: (w) -> | |
| y < 1 => x | |
| otherwise => w * (y - 1) + x | |
from-id = (i, w, h) -> | |
| i > (w - 1) * (h - 1) => false | |
| otherwise => new FlatVector (i % iw), (floor i / iw) + 1 | |
class World | |
(@width, @height) -> | |
@_cells = [] | |
@each (v) -> | |
@_cells[v.to-id!] = new Cell | |
each: -> (callback, endline-callback) ~> | |
for y til @width | |
for x til @height | |
callback new Vector x, y | |
endline-callback?! | |
get-cell-state: (v) ~> @_cells[v.to-id!]get-state! | |
set-cell-state: (v, s) ~> @_cells[v.to-id!]set-state s | |
get-neighbors: (v) ~> | |
# Each of these coordinates corresponds with a relative direction in two | |
# dimensions, in the order: | |
# NW, N, NE, W, E, SW, S, SE | |
n = [] | |
each [[-1 -1] [0 -1] [1 -1] [-1 0] [1 0], [-1 1] [0 1] [1 1]] ([x, y]) -> | |
n.push v.plus new FlatVector x, y | |
return n | |
get-num-living-neighbors: (v) ~> | |
length filter (n) -> | |
@_cells.get-cell-state n.to-id! is CellState.LIVE, @get-neighbors | |
class GameOfLife | |
(@world) -> | |
tick: -> | |
nw = new World @world.width!, @world.height! | |
@world.each (v) -> | |
c = v.get-num-living-neighbors! | |
state = switch c | |
| 3 => CellState.LIVE | |
| 2 => @world.get-cell-state v | |
| _ => CellState.DEAD | |
nw.set-cell-state v, state | |
@world = nw |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment