src/caves/core.clj @ ad823b5ba9cd entry-02
fix typo
| author | Steve Losh <steve@stevelosh.com> |
|---|---|
| date | Sun, 08 Jul 2012 09:09:21 -0400 |
| parents | 17efffc997c6 |
| children | a13a6a80dd59 |
(ns caves.core (:require [lanterna.screen :as s])) ; Data Structures ------------------------------------------------------------- (defrecord UI [kind]) (defrecord World []) (defrecord Game [world uis input]) ; Utility Functions ----------------------------------------------------------- (defn clear-screen [screen] (let [blank (apply str (repeat 80 \space))] (doseq [row (range 24)] (s/put-string screen 0 row blank)))) ; Drawing --------------------------------------------------------------------- (defmulti draw-ui (fn [ui game screen] (:kind ui))) (defmethod draw-ui :start [ui game screen] (s/put-string screen 0 0 "Welcome to the Caves of Clojure!") (s/put-string screen 0 1 "Press enter to win, anything else to lose.")) (defmethod draw-ui :win [ui game screen] (s/put-string screen 0 0 "Congratulations, you win!") (s/put-string screen 0 1 "Press escape to exit, anything else to restart.")) (defmethod draw-ui :lose [ui game screen] (s/put-string screen 0 0 "Sorry, better luck next time.") (s/put-string screen 0 1 "Press escape to exit, anything else to restart.")) (defn draw-game [game screen] (clear-screen screen) (doseq [ui (:uis game)] (draw-ui ui game screen)) (s/redraw screen)) ; Input ----------------------------------------------------------------------- (defmulti process-input (fn [game input] (:kind (last (:uis game))))) (defmethod process-input :start [game input] (if (= input :enter) (assoc game :uis [(new UI :win)]) (assoc game :uis [(new UI :lose)]))) (defmethod process-input :win [game input] (if (= input :escape) (assoc game :uis []) (assoc game :uis [(new UI :start)]))) (defmethod process-input :lose [game input] (if (= input :escape) (assoc game :uis []) (assoc game :uis [(new UI :start)]))) (defn get-input [game screen] (assoc game :input (s/get-key-blocking screen))) ; Main ------------------------------------------------------------------------ (defn run-game [game screen] (loop [{:keys [input uis] :as game} game] (when-not (empty? uis) (draw-game game screen) (if (nil? input) (recur (get-input game screen)) (recur (process-input (dissoc game :input) input)))))) (defn new-game [] (new Game (new World) [(new UI :start)] nil)) (defn main ([screen-type] (main screen-type false)) ([screen-type block?] (letfn [(go [] (let [screen (s/get-screen screen-type)] (s/in-screen screen (run-game (new-game) screen))))] (if block? (go) (future (go)))))) (defn -main [& args] (let [args (set args) screen-type (cond (args ":swing") :swing (args ":text") :text :else :auto)] (main screen-type true)))