53 lines
2.3 KiB
Plaintext
53 lines
2.3 KiB
Plaintext
(import (lib gl))
|
|
(import (otus random!))
|
|
|
|
(define WIDTH 170)
|
|
(define HEIGHT 96)
|
|
|
|
; probabilities
|
|
(define p 20)
|
|
(define f 1000)
|
|
|
|
(gl:set-window-title "Drossel and Schwabl 'forest-fire'")
|
|
(import (OpenGL version-1-0))
|
|
|
|
(glShadeModel GL_SMOOTH)
|
|
(glClearColor 0.11 0.11 0.11 1)
|
|
(glOrtho 0 WIDTH 0 HEIGHT 0 1)
|
|
|
|
(gl:set-userdata (make-vector (map (lambda (-) (make-vector (map (lambda (-) (rand! 2)) (iota WIDTH)))) (iota HEIGHT))))
|
|
|
|
(gl:set-renderer (lambda (mouse)
|
|
(let ((forest (gl:get-userdata))
|
|
(step (make-vector (map (lambda (-) (make-vector (repeat 0 WIDTH))) (iota HEIGHT)))))
|
|
(glClear GL_COLOR_BUFFER_BIT)
|
|
|
|
(glPointSize (/ 854 WIDTH))
|
|
(glBegin GL_POINTS)
|
|
(for-each (lambda (y)
|
|
(for-each (lambda (x)
|
|
(case (ref (ref forest y) x)
|
|
(0 ; An empty space fills with a tree with probability "p"
|
|
(if (zero? (rand! p))
|
|
(set-ref! (ref step y) x 1)))
|
|
(1
|
|
(glColor3f 0.2 0.7 0.2)
|
|
(glVertex2f x y)
|
|
; A tree will burn if at least one neighbor is burning
|
|
; A tree ignites with probability "f" even if no neighbor is burning
|
|
(if (or (eq? (ref (ref forest (- y 1)) (- x 1)) 2) (eq? (ref (ref forest (- y 1)) x) 2) (eq? (ref (ref forest (- y 1)) (+ x 1)) 2)
|
|
(eq? (ref (ref forest y ) (- x 1)) 2) (eq? (ref (ref forest y ) (+ x 1)) 2)
|
|
(eq? (ref (ref forest (+ y 1)) (- x 1)) 2) (eq? (ref (ref forest (+ y 1)) x) 2) (eq? (ref (ref forest (+ y 1)) (+ x 1)) 2)
|
|
(zero? (rand! f)))
|
|
(set-ref! (ref step y) x 2)
|
|
(set-ref! (ref step y) x 1)))
|
|
(2
|
|
(glColor3f 0.7 0.7 0.1)
|
|
(glVertex2f x y))
|
|
; A burning cell turns into an empty cell
|
|
(set-ref! (ref step y) x 0)))
|
|
(iota WIDTH)))
|
|
(iota HEIGHT))
|
|
(glEnd)
|
|
(gl:set-userdata step))))
|