-
Notifications
You must be signed in to change notification settings - Fork 0
/
gameoflife.scm
126 lines (108 loc) · 3.16 KB
/
gameoflife.scm
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
(define @matrix-w)
(define @matrix-h)
(define *matrix-neighbors)
(define *matrix-life)
; retrieve location on matrix by x/y
(define (matrix-pos M x y)
(if (or (< x 0)
(< y 0)
(>= x @matrix-w)
(>= y @matrix-h))
0
(list-ref (list-ref M y) x)))
; iterate row
(define (matrix-map~r R x y A f)
(if (null? R)
(reverse A)
(matrix-map~r (cdr R)
(+ x 1)
y
(cons (f (car R) x y)
A)
f)))
; iterate matrix
(define (matrix-map~ M y A f)
(if (null? M)
(reverse A)
(matrix-map~ (cdr M)
(+ y 1)
(cons (matrix-map~r (car M) 0 y '() f)
A)
f)))
; like map function but with matrix
(define (matrix-map f M)
(matrix-map~ M 0 '() f))
; tile display
(define (matrix-tile q)
(if (= q 1)
"()"
". "))
; display matrix
(define (matrix-display M)
(for-each (lambda (row)
(do (display (apply string-append
(map matrix-tile row)))
(newline)))
M))
; retrieve number of alive neighbor cells
(define (neighbors M x y)
(+ (matrix-pos M (- x 1) y)
(matrix-pos M (- x 1) (- y 1))
(matrix-pos M (- x 1) (+ y 1))
(matrix-pos M (+ x 1) y)
(matrix-pos M (+ x 1) (- y 1))
(matrix-pos M (+ x 1) (+ y 1))
(matrix-pos M x (+ y 1))
(matrix-pos M x (- y 1))))
; populate *matrix-neighbors list with data
(define (populate-neighbors)
(define *matrix-neighbors
(matrix-map (lambda (t x y)
(neighbors *matrix-life x y))
*matrix-life)))
; update cells based on neighbor data
(define (update-life)
(define *matrix-life
(matrix-map (lambda (t x y)
(cond ((or (< t 2)
(> t 3))
0)
((= t 3)
1)
(else (matrix-pos *matrix-life x y))))
*matrix-neighbors)))
; display life
(define (display-life)
(do (matrix-display *matrix-life)
(newline)))
; do it all
(define (life)
(do (display-life)
(populate-neighbors)
(update-life)))
; repeat utility
(define (repeat f times)
(if (<= times 0)
#!void
(do (f)
(repeat f (- times 1)))))
; example
(define *matrix-life '((0 1 0 0 0 0 0 0 0 0 0)
(0 0 1 0 0 0 0 0 0 0 0)
(1 1 1 0 0 0 0 0 0 0 0)
(0 0 0 0 0 0 0 0 0 0 0)
(0 0 0 0 0 0 0 0 1 0 0)
(0 0 0 0 0 0 0 0 1 0 0)
(0 0 0 0 0 0 0 0 1 0 0)
(0 0 0 0 0 0 0 0 0 0 0)
(0 0 0 0 0 0 0 0 0 0 0)))
; get size for later use
(define @matrix-w (length (car *matrix-life)))
(define @matrix-h (length *matrix-life))
; go!
(define (life-loop)
(do (life)
(if (eq? (read) "q")
#!void
(life-loop))))
(life-loop)