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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---