(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*)