-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathgame-of-life-2.clj
92 lines (82 loc) · 2.89 KB
/
game-of-life-2.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
;
; Missing features:
; - error control (ensure input is correct).
; - make it work for non-square matrices
; The namespace
(ns GameOfLife)
; Return the value of the cell at coordinates [x y] in the matrix.
; If the coordinates are outside of the matrix, then the value 0 is returned.
;
(defn get-value[x y matrix]
(if
(or (< x 0) (< y 0) (>= x (count matrix)) (>= y (count matrix)) )
0
((matrix x) y))
)
; Brute-force algorithm to calculate the number of living neighbours to a cell
; with coordinates [x y] in matrix. We assume (for the moment) that the value
; in a cell is either 0 or 1. (Need to control this at some stage!).
;
(defn count-living-neighbours [x y matrix]
(+
(get-value (- x 1) (- y 1) matrix)
(get-value x (- y 1) matrix)
(get-value (+ x 1) (- y 1) matrix)
(get-value (- x 1) y matrix)
(get-value (+ x 1) y matrix)
(get-value (- x 1) (+ y 1) matrix)
(get-value x (+ y 1) matrix)
(get-value (+ x 1) (+ y 1) matrix)
)
)
; Determine if a cell lives or dies in the next generation. Straight forward
; implementation of the algorithm on the blackboard.
;
(defn live-or-die? [x y matrix]
(cond
( < (count-living-neighbours x y matrix) 2) 0
( == (count-living-neighbours x y matrix) 2) (get-value x y matrix)
( == (count-living-neighbours x y matrix) 3) 1
( > (count-living-neighbours x y matrix) 3) 0
)
)
; Define a matrix for testing purposes.
(def test-matrix [ [0 1 0] [1 1 1] [1 0 0] ])
; Helper to visualize what's happening
(defn to-matrix-string [matrix]
(let [pretty-print-form (apply str (map #(str % \newline) matrix))]
pretty-print-form)
)
; This function creates a square matrix of dimension size x size.
; An entry in the matrix is a vector [rowNumber colNumber].
;
; Thus for the moment, the matrix of the game of life needs to be a square :-(
;
(defn get-coords [size]
(let
; The indices is a list of numbers in the range
[indices (range 0 size)
; row is a function that computes the vector of coordinates of the row
row (fn [y col] (vec (map #(vector y %) col)))]
(vec (map #(row % indices) (range 0 size))))
)
; The main() of the application.
; To solve the game of life, we .....
; - generate a matrix where each cell (value) is replaced by [x y] vector, the
; application of the function get-coords to the matrix size
; - generate a second new matrix result matrix where each coordinate matrix [x y]
; is replaced the value if live-or-die? for the original matrix, x and y
(defn game-of-life [matrix]
(let
[map-row (fn [col]
(vec (map #(live-or-die? (first %) (last %) matrix)
((get-coords (count matrix)) col))))]
(do
(print "Input matrix" \newline)
(print (to-matrix-string matrix))
(print "Output matrix" \newline)
(print (to-matrix-string (vec (map #(map-row %) (range 0 (count matrix))))))
"Au revoir ..."
)
)
)