Advertisement
Guest User

Game of Life

a guest
Mar 14th, 2018
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lisp 3.90 KB | None | 0 0
  1. ;;;; sdl2_test.lisp
  2.  
  3. (in-package #:sdl2_test)
  4. (require :sdl2)
  5.  
  6. (defparameter *size* 50)
  7. (defparameter *frame* '((-1 . -1) (0 . -1) (1 . -1) (-1 . 0) (1 . 0) (-1 . 1) (0 . 1) (1 . 1)))
  8. (defparameter *max-worlds* 2)
  9. (defparameter *current-world* 0)
  10. (defparameter *worlds* nil)
  11. (defparameter *tile-size* 10)
  12.  
  13. (defparameter *init-fields* '((3 . 3) (3 . 4) (3 . 5) (7 . 1) (8 . 2) (6 . 3) (7 . 3) (8 . 3)))
  14.  
  15. (defun init ()
  16.   (create-empty-worlds))
  17.  
  18. (defun create-empty-worlds ()
  19.   (progn
  20.     (setf *worlds* (make-array *max-worlds*))
  21.     (dotimes (n *max-worlds*)
  22.       (setf (aref *worlds* n) (create-empty-world)))))
  23.  
  24. (defun create-empty-world ()
  25.   (make-array (* *size* *size*) :initial-element nil))
  26.  
  27. (defun get-next-world-idx ()
  28.   (mod (1+ *current-world*) *max-worlds*))
  29.  
  30. (defun set-next-world-idx ()
  31.   (setf *current-world* (get-next-world-idx)))
  32.  
  33. (defun coord2idx (x y)
  34.   (+ (* y *size*) x))
  35.  
  36. (defun is-in-field (position)
  37.   (let ((x (car position))
  38.     (y (cdr position)))
  39.     (and (>= x 0) (>= y 0) (< x *size*) (< y *size*))))
  40.  
  41. (defun get-frame (position)
  42.   (let* ((x (car position))
  43.     (y (cdr position))
  44.     (frame (mapcar #'(lambda (delta-coord)
  45.                (let ((dx (car delta-coord))
  46.                  (dy (cdr delta-coord)))
  47.                  (cons (+ x dx) (+ y dy))))
  48.                *frame*)))
  49.     (remove-if-not #'is-in-field frame)))
  50.  
  51. (defun get-neighbor-idcs (position)
  52.   (mapcar #'(lambda (coord)
  53.           (let ((x-coord (car coord))
  54.             (y-coord (cdr coord)))
  55.         (coord2idx x-coord y-coord)))
  56.       (get-frame position)))
  57.  
  58. (defun count-neighbors (position world)
  59.   (let ((idcs (get-neighbor-idcs position)))
  60.     (list-length (remove-if-not #'(lambda (idx) (aref world idx)) idcs))))
  61.  
  62. (defun count-current-neighbors (position)
  63.   (count-neighbors position (aref *worlds* *current-world*)))
  64.  
  65. (defun get-self (position)
  66.   (aref (aref *worlds* *current-world*) (coord2idx (car position) (cdr position))))
  67.  
  68. (defun set-field (worlds-idx idx)
  69.   (setf (aref (aref *worlds* worlds-idx) idx) t))
  70.  
  71. (defun set-on-current (position)
  72.   (set-field *current-world* (coord2idx (car position) (cdr position))))
  73.  
  74. (defun clear-field (worlds-idx idx)
  75.   (setf (aref (aref *worlds* worlds-idx) idx) nil))
  76.  
  77. (defun set-value-on-field (worlds-idx idx value)
  78.   (setf (aref (aref *worlds* worlds-idx) idx) value))
  79.  
  80. (defun give-birth (num-neighbors)
  81.   (equal num-neighbors 3))
  82.  
  83. (defun die (num-neighbors)
  84.   (or (< num-neighbors 2) (> num-neighbors 3)))
  85.  
  86. (defun should-live (position)
  87.   (let ((neighbors (count-current-neighbors position))
  88.     (lives (get-self position)))
  89.     (or (give-birth neighbors) (and (not (die neighbors)) lives))))
  90.  
  91. (defun initialize-current-world-values ()
  92.   (mapcar #'set-on-current *init-fields*))
  93.  
  94. (defun world-step ()
  95.   (progn
  96.     (dotimes (x *size*)
  97.       (dotimes (y *size*)
  98.     (let* ((position (cons x y))
  99.            (idx (coord2idx x y))
  100.            (next-world (get-next-world-idx))
  101.            (value (should-live position)))
  102.       (set-value-on-field next-world idx value))))
  103.     (set-next-world-idx)))
  104.  
  105. (defun render-current-world (surface)
  106.   (dotimes (x *size*)
  107.     (dotimes (y *size*)
  108.       (let* ((value (get-self (cons x y)))
  109.          (color (if value
  110.             (sdl2:map-rgb (sdl2:surface-format surface) #xaa #x00 #xcc)
  111.             (sdl2:map-rgb (sdl2:surface-format surface) #x00 #x00 #xbb))))
  112.     (progn
  113.      
  114.       (sdl2:fill-rect surface (sdl2:make-rect (* x *tile-size*) (* y *tile-size*) *tile-size* *tile-size*) color))))))
  115.  
  116. (defun main ()
  117.   (sdl2:with-init (:everything)
  118.     (sdl2:with-window (win :title "Game of Life" :flags '(:shown))
  119.       (let ((surf (sdl2:get-window-surface win)))
  120.     (progn
  121.       (init)
  122.       (initialize-current-world-values)
  123.       (sdl2:with-event-loop (:method :poll)
  124.         (:quit () t)
  125.         (:idle ()
  126.            (sdl2:fill-rect surf nil (sdl2:map-rgb (sdl2:surface-format surf) #xff #xff #xff))
  127.            (render-current-world surf)
  128.            (world-step)
  129.            (sdl2:update-window win)
  130.            (sdl2:delay 200))))))))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement