As I'm currently trying to learn clojure I wrote a game of life to get a 
feeling for the concepts.
It would be great if some of you could point out areas for improvement or 
unused idioms or patterns.

Thanks alot

Michael

here is the code:
(ns gol)
(comment "a board only contains the coordinates of living cells")

(def matrix #{[-1 -1] [-1 0] [-1 1] [0 -1] [0 0] [0 1] [1 -1] [1 0] [1 1]})

(def size 3)

(defn neighbours
   "All direct neighbours around [pos] and pos itself"
   [pos]
   (defn translate [[x y]] [(+ x (first pos)) (+ y (second pos))])
   (map translate matrix)
)

(defn alive
       "is pos alive in the next turn"
   [pos board]
   (defn count-living [cnt p] (if (contains? board p) (inc cnt) cnt))
   (defn gets-a-life [living-neighbours]
     (or (and (not (contains? board pos)) (= living-neighbours 3))
        (and (contains? board pos) (contains? #{3 4} living-neighbours)))
     )
   (gets-a-life (reduce count-living 0 (neighbours pos)))
   )

(defn all-neighbours
     "all direct neighbours of all living cells on the board"
  [size board]
  (defn on-board [[x y]] (and (>= x 0) (< x size) (>= y 0) (< y size)))
  (set (filter on-board (mapcat #(neighbours %) board)))
)

(defn next-board
   "calculates the new board"
   ([board] (next-board size board))
   ([bsize board]
          (let [
            new-board (map
                       (fn [[x y]] (if (alive [x y] board) [x y] nil))
                       (all-neighbours bsize board))
            ]
             (set (filter #(not (nil? %)) new-board))))
   )

(defn to-string
     "creates a string representation of a board"
     ([board] (to-string size board))
     ([bsize board]
   (def axis (range bsize))
   (reduce
    (fn [text x]
        (str text (reduce
        (fn [text y]
            (str text (if (contains? board [x y]) "#" "_"))
            )
            "" axis)
         "\n")) "" axis)))

(defn time-it
     "calculates a board of a certain size n times and prints the time"
     [cnt size board]
       (time (loop [x cnt
               b board]
               (if (zero? x) (to-string b)
               (recur (dec x) (next-board size b)))))
)

(def start-board #{[0 0] [1 1] [0 1] [2 2]})

(defn demo
"runs a simple board 10 times"
[]
(map
  #(println (to-string %))
  (take 10 (iterate next-board start-board))
))


(defn next-board-old
     "old version that evaluated the whole board"
     ([board] (next-board size board))
                 ([bsize board]
   (let [
       axis (range bsize)
       new-board (map (fn [x] (map (fn [y] (if (alive [x y] board) [x y] nil)) 
axis)) axis)
       ]
       (set (filter #(not (nil? %)) (mapcat (fn [x] x) new-board))))
   )
)


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to