(require '[clojure.string :as s]) | |
(declare print-maze) | |
;; Maze GENERATION | |
(defn create-grid [rows cols] | |
(vec (repeat rows (vec (repeat cols #{}))))) | |
(defn north-of [[row col]] [(dec row) col]) | |
(defn south-of [[row col]] [(inc row) col]) | |
(defn west-of [[row col]] [row (dec col)]) | |
(defn east-of [[row col]] [row (inc col)]) | |
(defn neighbours [grid cell] | |
(filter #(get-in grid %) ((juxt north-of east-of south-of west-of) cell))) | |
(defn remove-border [grid c1 c2] | |
(-> grid | |
(update-in c1 conj c2) | |
(update-in c2 conj c1))) | |
(defn find-unvisited-neighbours [grid cell] | |
(let [n (neighbours grid cell)] | |
(filter #(empty? (get-in grid %)) n))) | |
(defn generate-maze [rows cols] | |
(loop [maze (create-grid rows cols) | |
backtrackstack '([0 0])] | |
(if (empty? backtrackstack) | |
(print-maze maze) | |
(let [unvn (find-unvisited-neighbours maze (first backtrackstack))] | |
(if (empty? unvn) | |
(recur maze (rest backtrackstack)) | |
(let [next (rand-nth unvn)] | |
(recur | |
(remove-border maze (first backtrackstack) next) | |
(conj backtrackstack next)))))))) | |
;; Maze PRINTING | |
(defn east-open-border? [maze cell] | |
(contains? (get-in maze (east-of cell)) cell)) | |
(defn south-open-border? [maze cell] | |
(contains? (get-in maze (south-of cell)) cell)) | |
(defn print-cell-body [maze cell] | |
(if (east-open-border? maze cell) | |
" " | |
" |")) | |
(defn print-cell-bottom [maze cell] | |
(if (south-open-border? maze cell) | |
" +" | |
"---+")) | |
(defn print-maze [maze] | |
(let [result (atom []) | |
rows (range (count maze)) | |
cols (range (count (get-in maze [0])))] | |
(swap! result conj "+" (repeat (count cols) "---+") "\n") | |
(doseq [row rows] | |
(swap! result conj "|") | |
(doseq [col cols] | |
(swap! result conj (print-cell-body maze [row col]))) | |
(swap! result conj "\n" "+") | |
(doseq [col cols] | |
(swap! result conj (print-cell-bottom maze [row col]))) | |
(swap! result conj "\n")) | |
(println (s/join (flatten @result))))) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment