blob: ad5bbf6356b4f64b9e4acac5a13f5a2c0cd2cc10 (
plain)
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
|
#lang racket
(require graphics/graphics)
(require racket/bool)
(define screen-width 600)
(define screen-height screen-width)
(define board-width 15)
(define board-height 15)
(define cell-vertical-size (/ screen-width board-width))
(define cell-horizontal-size (/ screen-height board-height))
(define line-color (make-rgb 0.8 0.8 0.8))
(define cell-color (make-rgb 0.95 0.95 0))
(define starting-board (set '(1 0)
'(2 1)
'(0 2)
'(1 2)
'(2 2)))
(open-graphics)
(define w (open-viewport "Game of Life"
screen-width
screen-height))
(define (draw-vertical-lines coord step)
(cond
[(< coord screen-width) (begin
((draw-line w) (make-posn coord 0)
(make-posn coord screen-height)
line-color)
(draw-vertical-lines (+ coord step) step))]))
(define (draw-horizontal-lines coord step)
(cond
[(< coord screen-width) (begin
((draw-line w) (make-posn 0 coord)
(make-posn screen-height coord)
line-color)
(draw-horizontal-lines (+ coord step) step))]))
(define (draw-lines width height)
(draw-vertical-lines cell-vertical-size cell-vertical-size)
(draw-horizontal-lines cell-horizontal-size cell-horizontal-size))
(define (draw-cell cell)
((draw-solid-ellipse w) (make-posn (* cell-horizontal-size (car cell))
(* cell-horizontal-size (car (cdr cell))))
cell-vertical-size
cell-horizontal-size
cell-color))
(define (draw-board board)
(for ([cell board])
(draw-cell cell)))
(define (count-alive-neighbors orig-cell board)
(let* ([orig-x (car orig-cell)]
[orig-y (car (cdr orig-cell))])
(define (iterate y sum)
(define (iterate-row x row-sum)
(let ([cell (list x y)])
(if (<= x (+ orig-x 1))
(iterate-row (+ x 1) (if (set-member? board cell)
(+ row-sum 1)
row-sum))
row-sum)))
(if (<= y (+ orig-y 1)) (iterate (+ y 1)
(+ sum
(iterate-row (- orig-x 1) 0)))
sum))
(let ([neighbors (iterate (- orig-y 1) 0)])
(if (set-member? board orig-cell)
(- neighbors 1)
neighbors))))
(define (will-be-alive cell board)
(let* ([alive-neighbors (count-alive-neighbors cell board)]
[is-alive (set-member? board cell)])
(or
(and is-alive (or (eq? alive-neighbors 2) (eq? alive-neighbors 3)))
(and (not is-alive) (eq? alive-neighbors 3)))))
(define (next-generation current-board)
(define new-board (mutable-set))
(define (iterate y)
(define (iterate-row x)
(let ([cell (list x y)])
(cond [(will-be-alive cell current-board) (set-add! new-board cell)])
(cond [(< x board-width) (iterate-row (+ x 1))])))
(iterate-row 0)
(cond [(< y board-height) (iterate (+ y 1))]))
(iterate 0)
new-board)
(define (play board)
((clear-viewport w))
(draw-lines board-width board-height)
(draw-board board)
(sleep 0.5)
(play (next-generation board)))
(play starting-board)
(close-graphics)
|