Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
(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
You can’t perform that action at this time.