57 lines
1.6 KiB
Common Lisp
57 lines
1.6 KiB
Common Lisp
(setf *random-state* (make-random-state t))
|
|
|
|
(defun 2d-array (w h)
|
|
(make-array (list h w) :initial-element 0))
|
|
|
|
(defmacro or-and (v a b c)
|
|
`(if (or ,a (and ,b (= 1 ,c))) 0 ,v))
|
|
|
|
(defun make-maze (w h)
|
|
(let ((vis (2d-array w h))
|
|
(ver (2d-array w h))
|
|
(hor (2d-array w h)))
|
|
(labels
|
|
((walk (y x)
|
|
(setf (aref vis y x) 1)
|
|
(loop
|
|
(let (x2 y2)
|
|
(loop for (dx dy) in '((-1 0) (1 0) (0 -1) (0 1))
|
|
with cnt = 0 do
|
|
(let ((xx (+ x dx))
|
|
(yy (+ y dy)))
|
|
(if (and (array-in-bounds-p vis yy xx)
|
|
(zerop (aref vis yy xx))
|
|
(zerop (random (incf cnt))))
|
|
(setf x2 xx y2 yy))))
|
|
(if (not x2) (return-from walk))
|
|
(if (= x x2)
|
|
(setf (aref hor (min y y2) x) 1)
|
|
(setf (aref ver y (min x x2)) 1))
|
|
(walk y2 x2))))
|
|
|
|
(show ()
|
|
(let ((g " │││─┘┐┤─└┌├─┴┬┼"))
|
|
(loop for i from 0 to h do
|
|
(loop for j from 0 to w do
|
|
(format t "~c~a"
|
|
(char g
|
|
(+ (or-and 1 (= i 0) (> j 0) (aref ver (1- i) (1- j)))
|
|
(or-and 2 (= i h) (> j 0) (aref ver i (1- j)))
|
|
(or-and 4 (= j 0) (> i 0) (aref hor (1- i) (1- j)))
|
|
(or-and 8 (= j w) (> i 0) (aref hor (1- i) j ))))
|
|
(if (and (< j w)
|
|
(or (= i 0)
|
|
(= 0 (aref hor (1- i) j))))
|
|
"───" " ")))
|
|
(terpri)
|
|
(when (< i h)
|
|
(loop for j from 0 below w do
|
|
(format t (if (or (= j 0)
|
|
(= 0 (aref ver i (1- j))))
|
|
"│ " " ")))
|
|
(format t "│~%"))))))
|
|
|
|
(walk (random h) (random w))
|
|
(show))))
|
|
|
|
(make-maze 20 20)
|