aboutsummaryrefslogtreecommitdiff
path: root/src/gol.lisp
blob: d954583df554d61e9fad9b31b010faf7b6714280 (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
(in-package #:gol)

(asdf:load-systems :alexandria
                   :sdl2)
(use-package :alexandria)

(deftype grid (width height)
  `(array integer (,width ,height)))

(defun next-generation (grid result)
  (assert (equal (array-dimensions grid) (array-dimensions result)))
  (destructuring-bind (m n) (array-dimensions grid)
    (flet ((cell-value (i j)
             (- (loop :for u :from (1- i) :repeat 3
                    :summing
                    (loop :for v :from (1- j) :repeat 3
                          :summing (aref grid (mod u m) (mod v n))))
                (aref grid i j))))
      (dotimes (i m)
        (dotimes (j n)
          (let ((x (aref grid i j))
                (y (cell-value i j)))
            (setf (aref result i j)
                  (if (zerop x)
                      (if (= y 3) 1 0)
                      (if (or (= y 2) (= y 3)) 1 0)))))))))

(defun draw-grid (renderer grid &key (cell-w 10) (cell-h 10))
  (destructuring-bind (m n) (array-dimensions grid)
    (dotimes (i m)
      (dotimes (j n)
        (let ((rect (sdl2:make-rect (* i cell-h) (* j cell-w) cell-w cell-h)))
          (sdl2:render-draw-rect renderer rect)
          (unless (zerop (aref grid i j))
            (sdl2:render-fill-rect renderer rect)))))))

(defun run ()
  (sdl2:with-init (:everything)
    (sdl2:with-window (window)
      (sdl2:with-renderer (renderer window)
        (sdl2:with-event-loop ()
          (:idle ()
                 (sdl2:set-render-draw-color renderer 255 255 255 255)
                 (sdl2:render-clear renderer)
                 (sdl2:set-render-draw-color renderer 0 0 0 255)
                 (draw-grid renderer *grid1*)
                 (sdl2:render-present renderer)
                 (sdl2:delay 200)
                 (next-generation *grid1* *grid2*)
                 (rotatef *grid1* *grid2*))
          (:quit () t))))))


(defparameter *grid1* (make-array '(20 20) :initial-element 0))
(defparameter *grid2* (make-array '(20 20) :initial-element 0))

(setf (aref *grid1* 0 0) 1
      (aref *grid1* 1 0) 1
      (aref *grid1* 1 1) 1
      (aref *grid1* 2 1) 1
      (aref *grid1* 0 2) 1)

(run)

*grid1*
*grid2*

(progn
  (next-generation *grid1* *grid2*)
  (rotatef *grid1* *grid2*)
  *grid2*)