Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
(ns ^{:doc "Conway's Game of Life."}
;; Core game of life's algorithm functions
(defn neighbours
"Given a cell natural identifier, returns the natural identifiers
of the neighbours of the cell.
In this implementation, the natural identifier of the cell is its [x, y]
[[x y]]
(for [dx [-1 0 1] dy (if (zero? dx) [-1 1] [-1 0 1])]
[(+ dx x) (+ dy y)]))
(defn step
"Given a set of living cells (representing the state of the game at step N-1),
computes the new set of living cells (representing the state of the game at step N)
by applying the usual rules.
Implementation detail:
- (frequencies ...) returns a map of entries [cell n] where cell
is a cell natural identifier, n the number of living cells (at step N-1) around it.
- (for ...) is a list comprehension which, for each cell surrounded by n living cells,A
computes whether the cell survives (let cell be part of the list) or dies."
(set (for [[cell n] (frequencies (mapcat neighbours cells))
:when (or (= n 3) (and (= n 2) (cells cell)))]
;; Utility methods for displaying game on a text terminal
(defn print-board
"Prints a board (up to w cells as width, h cells as height) on *out*"
[board w h]
(doseq [x (range (inc w)) y (range (inc h))]
(if (= y 0) (print "\n"))
(print (if (board [x y]) "[X]" " . "))))
(defn display-grids
"Prints on *out* a sequence of boards representing the states of the game at each step"
[grids w h]
(doseq [board grids]
(print-board board w h)
(print "\n")))
;; Launches an example board
^{:doc "board represents the initial state of the game, e.g. a set of living cells"}
board #{[2 1] [2 2] [2 3]})
(display-grids (take 3 (iterate step board)) 5 5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.