Arantium Maestum

プログラミング、囲碁、読書の話題

ClojureでGame of Lifeを書いてみた

Conway's Game of LifeClojureで実装してみる。

何となく簡単そうだったので試してみたら、やっぱり簡単だった。

主要なロジックは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的に見れるようにしてみたい。

続く