~ chicken-core (master) /tests/life.scm
Trap1;;; The following example shows how a program can be divided into libraries plus a
2;;; relatively small main program.
3
4(define-library (example grid)
5 (export make rows cols ref each
6 (rename put! set!))
7 (import (scheme base))
8 (begin
9 ;; Create an NxM grid.
10 (define (make n m)
11 (let ((grid (make-vector n)))
12 (do ((i 0 (+ i 1)))
13 ((= i n) grid)
14 (let ((v (make-vector m #false)))
15 (vector-set! grid i v)))))
16 (define (rows grid)
17 (vector-length grid))
18 (define (cols grid)
19 (vector-length (vector-ref grid 0)))
20 (define (ref grid n m)
21 (vector-ref (vector-ref grid (modulo n (rows grid))) (modulo m (cols grid))))
22 (define (put! grid n m v)
23 (vector-set! (vector-ref grid n) m v))
24 (define (each grid proc)
25 (do ((j 0 (+ j 1)))
26 ((= j (rows grid)))
27 (do ((k 0 (+ k 1)))
28 ((= k (cols grid)))
29 (proc j k (ref grid j k)))))))
30
31(define-library (example life)
32 (export life)
33 (import (except (scheme base) set!)
34 (scheme write)
35 (example grid))
36 (begin
37 (define (life-count grid i j)
38 (define (count i j)
39 (if (ref grid i j) 1 0))
40 (+ (count (- i 1) (- j 1))
41 (count (- i 1) j)
42 (count (- i 1) (+ j 1))
43 (count i (- j 1))
44 (count i (+ j 1))
45 (count (+ i 1) (- j 1))
46 (count (+ i 1) j)
47 (count (+ i 1) (+ j 1))))
48 (define (life-alive? grid i j)
49 (case (life-count grid i j)
50 ((3) #true)
51 ((2) (ref grid i j))
52 (else #false)))
53 (define (life-print grid)
54 (newline) ;(display "\x1B;[1H\x1B;[J") ; clear vt100
55 (each grid
56 (lambda (i j v)
57 (display (if v "*" " "))
58 (when (= j (- (cols grid) 1))
59 (newline)))))
60 (define (life grid iterations)
61 (do ((i 0 (+ i 1))
62 (grid0 grid grid1)
63 (grid1 (make (rows grid) (cols grid))
64 grid0))
65 ((= i iterations))
66 (each grid0
67 (lambda (j k v)
68 (let ((a (life-alive? grid0 j k)))
69 (set! grid1 j k a))))
70 (life-print grid1)))))
71
72;; Main program.
73(import (only (example life) life)
74 (rename (prefix (example grid) grid-)
75 (grid-make make-grid)))
76
77;; Initialize a grid with a glider.
78(define grid (make-grid 8 8))
79(grid-set! grid 1 1 #true)
80(grid-set! grid 2 2 #true)
81(grid-set! grid 3 0 #true)
82(grid-set! grid 3 1 #true)
83(grid-set! grid 3 2 #true)
84
85;; Run for 40 iterations.
86(life grid 40)