RosettaCodeData/Task/Maze-generation/Ol/maze-generation-1.ol
2023-07-01 13:44:08 -04:00

37 lines
1.3 KiB
Text

; maze generation
(import (otus random!))
(define WIDTH 30)
(define HEIGHT 8)
(define maze
(map (lambda (?)
(repeat #b01111 WIDTH)) ; 0 - unvisited, 1111 - all walls exists
(iota HEIGHT)))
(define (at x y)
(list-ref (list-ref maze y) x))
(define (unvisited? x y)
(if (and (< -1 x WIDTH) (< -1 y HEIGHT))
(zero? (band (at x y) #b10000))))
(define neighbors '((-1 . 0) (0 . -1) (+1 . 0) (0 . +1)))
(define walls '( #b10111 #b11011 #b11101 #b11110))
(define antiwalls '( #b11101 #b11110 #b10111 #b11011))
(let loop ((x (rand! WIDTH)) (y (rand! HEIGHT)))
(list-set! (list-ref maze y) x (bor (at x y) #b10000))
(let try ()
(if (or
(unvisited? (- x 1) y) ; left
(unvisited? x (- y 1)) ; top
(unvisited? (+ x 1) y) ; right
(unvisited? x (+ y 1))) ; bottom
(let*((p (rand! 4))
(neighbor (list-ref neighbors p)))
(let ((nx (+ x (car neighbor)))
(ny (+ y (cdr neighbor))))
(if (unvisited? nx ny)
(let ((ncell (at nx ny)))
(list-set! (list-ref maze y) x (band (at x y) (list-ref walls p)))
(list-set! (list-ref maze ny) nx (band ncell (list-ref antiwalls p)))
(loop nx ny)))
(try))))))