71 lines
1.9 KiB
Text
71 lines
1.9 KiB
Text
#!/usr/bin/ol
|
|
(import (otus random!))
|
|
|
|
(define MAX 65536) ; should be power of two
|
|
; size of game board (should be less than MAX)
|
|
(define WIDTH 170)
|
|
(define HEIGHT 96)
|
|
|
|
; helper function
|
|
(define (hash x y)
|
|
(let ((x (mod (+ x WIDTH) WIDTH))
|
|
(y (mod (+ y HEIGHT) HEIGHT)))
|
|
(+ (* y MAX) x)))
|
|
|
|
;; ; helper function
|
|
(define directions '(
|
|
(0 . 1) (1 . 0) (0 . -1) (-1 . 0)
|
|
))
|
|
|
|
; ---------------
|
|
(import (lib gl2))
|
|
(gl:set-window-title "Langton's Ant")
|
|
|
|
(glShadeModel GL_SMOOTH)
|
|
(glClearColor 0.11 0.11 0.11 1)
|
|
(glOrtho 0 WIDTH 0 HEIGHT 0 1)
|
|
|
|
(glPointSize (/ 854 WIDTH))
|
|
|
|
; generate random field
|
|
(gl:set-userdata
|
|
(list->ff (map (lambda (i) (let ((x (rand! WIDTH)) (y (rand! HEIGHT)))
|
|
(cons (hash x y) #t))) (iota 1000))))
|
|
|
|
(define ant (cons
|
|
(rand! WIDTH)
|
|
(rand! HEIGHT)))
|
|
(define dir (list (rand! 4))) ; 0, 1, 2, 3
|
|
|
|
; main game loop
|
|
(gl:set-renderer (lambda (mouse)
|
|
(let ((generation (gl:get-userdata)))
|
|
(glClear GL_COLOR_BUFFER_BIT)
|
|
|
|
; draw the cells
|
|
(glColor3f 0.2 0.5 0.2)
|
|
(glBegin GL_POINTS)
|
|
(ff-fold (lambda (st key value)
|
|
(glVertex2f (mod key MAX)
|
|
(div key MAX))
|
|
) #f generation)
|
|
(glColor3f 0.8 0.2 0.1)
|
|
(glVertex2f (car ant) (cdr ant))
|
|
(glEnd)
|
|
|
|
(gl:set-userdata
|
|
(let*((x (car ant))
|
|
(y (cdr ant))
|
|
(generation (case (get generation (hash x y) #f)
|
|
(#true ; black cell
|
|
(set-car! dir (mod (+ (car dir) 1) 4))
|
|
(del generation (hash x y)))
|
|
(#false
|
|
(set-car! dir (mod (+ (car dir) 7) 4))
|
|
(put generation (hash x y) #true)))))
|
|
(set-car! ant (mod (+ x (car (lref directions (car dir)))) WIDTH))
|
|
(set-cdr! ant (mod (+ y (cdr (lref directions (car dir)))) HEIGHT))
|
|
generation))
|
|
|
|
|
|
)))
|