Skip to content

Instantly share code, notes, and snippets.

@joelittlejohn
Last active December 15, 2015 10:49
Show Gist options
  • Save joelittlejohn/5248744 to your computer and use it in GitHub Desktop.
Save joelittlejohn/5248744 to your computer and use it in GitHub Desktop.
BrisFunctional sokoban
(ns sokoban.core)
(comment #{:n :s :e :w})
(def start-world
{:person [3 1]
:targets #{[1 3]}
:crates #{[1 2]}
:blanks #{[1 3] [2 3] [3 3]
[1 2] [3 2]
[1 1] [2 1] [3 1]}})
(defn printable-char [world pos]
(cond
(= pos (world :person)) "&"
(and ((world :crates) pos)
((world :targets) pos)) "0"
((world :crates) pos) "O"
((world :targets) pos) "."
((world :blanks) pos) " "
:else "#"))
(defn generate-next-world [world move]
(println move)
;; is the move legal?
;; - person moving into blank?
;; - person moving onto crate?
;; - crate moving onto blank?
;; if so, move person & move crate
world)
(defn read-user-input []
(let [c (read-line)]
(condp = c
"w" :n
"a" :w
"s" :s
"d" :e
(recur))))
(defn print-the-world [world]
(let [extents (apply (partial map max) (world :blanks))]
(doseq [x (range 0 (+ 2 (first extents)))]
(do (doseq [y (range 0 (+ 2 (second extents)))]
(print (printable-char world [x y])))
(println)))))
(defn won? [world]
(= (world :targets) (world :crates)))
(defn do-turn [world]
(print-the-world world)
(let [input (read-user-input)]
(generate-next-world world input)))
(defn game-loop [world]
(if (won? world)
(do (print-the-world world)
(print "YAY!"))
(recur (do-turn world))))
(game-loop start-world)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment