ClojureでGame of Lifeを書いてみた
Conway's Game of LifeをClojureで実装してみる。
何となく簡単そうだったので試してみたら、やっぱり簡単だった。
主要なロジックはnext-round関数にほぼ収まりきっている。個人的にはかなり宣言的にゲームのルールを記述するところが大部分を占めているように思うのでプチ満足。
(defn next-round [live-cells] (letfn [(surrounding [[cell-x cell-y]] (for [x [-1 0 1] y [-1 0 1] :when (not (= 0 x y))] [(+ cell-x x) (+ cell-y y)])) (living-count [cells] (count (clojure.set/intersection live-cells (set cells)))) (dead-to-life? [dead-cell] (= 3 (living-count (surrounding dead-cell)))) (remain-alive? [live-cell] (< 1 (living-count (surrounding live-cell)) 4))] (let [surrounds (->> live-cells (map surrounding) (apply concat) distinct) new-alive (->> surrounds (remove live-cells) (filter dead-to-life?)) remains (filter remain-alive? live-cells)] (clojure.set/union (set new-alive) (set remains)))))
使い方としては例えばこう:
(->> #{[0 0] [1 1] [1 0] [0 1] [2 0]} (iterate next-round) (take 10) (map println) doall)
これは結構すぐ死滅するのがわかる。
次はこのnext-round関数をQuilにつなげてGUI的に見れるようにしてみたい。