123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- ;;; game-of-life --- Conway's Game of Life in Pre-Scheme
- (define WINDOW_TITLE "Conway's Game of Life")
- (define WINDOW_WIDTH 1280)
- (define WINDOW_HEIGHT 800)
- (define CELL_SIZE 5)
- (define FRAME_DELAY 50)
- (define GRID_WIDTH (quotient WINDOW_WIDTH CELL_SIZE))
- (define GRID_HEIGHT (quotient WINDOW_HEIGHT CELL_SIZE))
- (define (main argc argv)
- (ensure-args argc argv)
- (with-sdl
- (sdl-init SDL_INIT_VIDEO)
- (lambda ()
- (with-sdl-window
- (sdl-create-window WINDOW_TITLE
- SDL_WINDOWPOS_CENTERED
- SDL_WINDOWPOS_CENTERED
- WINDOW_WIDTH
- WINDOW_HEIGHT
- SDL_WINDOW_SHOWN)
- (lambda (window)
- (with-sdl-renderer
- (sdl-create-renderer window -1 SDL_RENDERER_ACCELERATED)
- (lambda (renderer)
- (with-sdl-event
- (lambda (event)
- (run-application window renderer event))))))))))
- (define (ensure-args argc argv)
- ;; type inference hack to get the right signature for main
- (string-length (vector-ref argv (- argc 1)))
- (unspecific))
- (define (handle-sdl-error message)
- (define out (current-error-port))
- (write-string message out)
- (write-string ": " out)
- (write-string (sdl-get-error) out)
- (newline out)
- -1)
- (define (with-sdl initialized? thunk)
- (if (not initialized?)
- (handle-sdl-error "Could not initialize SDL")
- (let ((result (thunk)))
- (sdl-quit)
- result)))
- (define (with-sdl-window window proc)
- (if (null-pointer? window)
- (handle-sdl-error "Could not create window")
- (let ((result (proc window)))
- (sdl-destroy-window window)
- result)))
- (define (with-sdl-renderer renderer proc)
- (if (null-pointer? renderer)
- (handle-sdl-error "Could not create renderer")
- (let ((result (proc renderer)))
- (sdl-destroy-renderer renderer)
- result)))
- (define (with-sdl-event proc)
- (let* ((event (sdl-create-event))
- (result (proc event)))
- (sdl-destroy-event event)
- result))
- (define (run-application window renderer event)
- (let ((grid (initialize-grid)))
- (let loop ((running? #t))
- (when running?
- (cond ((sdl-poll-event event)
- (if (= (sdl-event-type event) SDL_QUIT)
- (goto loop #f)
- (goto loop #t)))
- (else
- (update-grid grid)
- (render-grid grid renderer)
- (sdl-delay FRAME_DELAY)
- (goto loop #t)))))
- (destroy-grid grid)
- 0))
- (define (initialize-grid)
- (define c_srand (external "srand" (=> (integer) unit)))
- (define c_rand (external "rand" (=> () integer)))
- (define c_time (external "time" (=> (integer) integer)))
- (c_srand (c_time 0))
- (grid-unfold (lambda (ix x y)
- (remainder (c_rand) 2))
- GRID_WIDTH GRID_HEIGHT))
- (define (update-grid grid)
- (grid-update! (lambda (ix x y value)
- (let ((north (grid-ref grid x (- y 1)))
- (south (grid-ref grid x (+ y 1)))
- (east (grid-ref grid (+ x 1) y))
- (west (grid-ref grid (- x 1) y))
- (north-east (grid-ref grid (+ x 1) (- y 1)))
- (north-west (grid-ref grid (- x 1) (- y 1)))
- (south-east (grid-ref grid (+ x 1) (+ y 1)))
- (south-west (grid-ref grid (- x 1) (+ y 1))))
- (let ((alive? (one? value))
- (live-neighbours (+ north south east west
- north-east north-west
- south-east south-west)))
- (if alive?
- (cond ((< live-neighbours 2) 0) ;; underpopulation
- ((> live-neighbours 3) 0) ;; overpopulation
- (else 1))
- (cond ((= live-neighbours 3) 1) ;; reproduction
- (else 0))))))
- grid))
- (define (render-grid grid renderer)
- (sdl-set-render-draw-color renderer 0 0 0 255)
- (sdl-render-clear renderer)
- (sdl-set-render-draw-color renderer 255 255 255 255)
- (grid-for-each (lambda (ix x y value)
- (unless (zero? value)
- (sdl-render-fill-rect renderer
- (* x CELL_SIZE)
- (* y CELL_SIZE)
- CELL_SIZE
- CELL_SIZE)
- (unspecific)))
- grid)
- (sdl-render-present renderer)
- (unspecific))
|