2018-11-19 07:15:21 +00:00
|
|
|
# A game of life implementation
|
|
|
|
|
2018-11-21 02:48:06 +00:00
|
|
|
(def- window
|
2018-11-29 18:30:59 +00:00
|
|
|
(seq [x :range [-1 2]
|
2018-11-19 07:15:21 +00:00
|
|
|
y :range [-1 2]
|
|
|
|
:when (not (and (zero? x) (zero? y)))]
|
2019-02-17 16:20:24 +00:00
|
|
|
[x y]))
|
2018-11-19 07:15:21 +00:00
|
|
|
|
|
|
|
(defn- neighbors
|
|
|
|
[[x y]]
|
2019-02-17 16:20:24 +00:00
|
|
|
(map (fn [[x1 y1]] [(+ x x1) (+ y y1)]) window))
|
2018-11-19 07:15:21 +00:00
|
|
|
|
|
|
|
(defn tick
|
|
|
|
"Get the next state in the Game Of Life."
|
|
|
|
[state]
|
2018-11-21 02:48:06 +00:00
|
|
|
(def cell-set (frequencies state))
|
|
|
|
(def neighbor-set (frequencies (mapcat neighbors state)))
|
2018-11-29 18:30:59 +00:00
|
|
|
(seq [coord :keys neighbor-set
|
2019-01-07 00:33:27 +00:00
|
|
|
:let [count (get neighbor-set coord)]
|
2018-11-21 02:48:06 +00:00
|
|
|
:when (or (= count 3) (and (get cell-set coord) (= count 2)))]
|
|
|
|
coord))
|
2018-11-19 07:15:21 +00:00
|
|
|
|
|
|
|
(defn draw
|
|
|
|
"Draw cells in the game of life from (x1, y1) to (x2, y2)"
|
|
|
|
[state x1 y1 x2 y2]
|
2018-11-21 02:48:06 +00:00
|
|
|
(def cellset @{})
|
2019-01-07 00:33:27 +00:00
|
|
|
(each cell state (put cellset cell true))
|
2018-11-27 03:09:12 +00:00
|
|
|
(loop [x :range [x1 (+ 1 x2)]
|
|
|
|
:after (print)
|
2018-11-19 07:15:21 +00:00
|
|
|
y :range [y1 (+ 1 y2)]]
|
2019-02-17 16:20:24 +00:00
|
|
|
(file/write stdout (if (get cellset [x y]) "X " ". ")))
|
2018-11-19 07:15:21 +00:00
|
|
|
(print))
|
|
|
|
|
|
|
|
#
|
|
|
|
# Run the example
|
|
|
|
#
|
|
|
|
|
2018-11-21 02:48:06 +00:00
|
|
|
(var *state* '[(0 0) (-1 0) (1 0) (1 1) (0 2)])
|
2018-11-19 07:15:21 +00:00
|
|
|
|
2018-11-29 18:30:59 +00:00
|
|
|
(for i 0 20
|
2018-11-19 07:15:21 +00:00
|
|
|
(print "generation " i)
|
|
|
|
(draw *state* -7 -7 7 7)
|
2018-12-17 02:57:32 +00:00
|
|
|
(set *state* (tick *state*)))
|