From 60c1ac2ca3e47d1074838b2752694b3026f3bcfd Mon Sep 17 00:00:00 2001 From: = Date: Fri, 12 Sep 2014 17:54:57 -0700 Subject: [PATCH] added a spike for scripting using macros. --- desktop/src-common/advent/action_test.clj | 93 +++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 desktop/src-common/advent/action_test.clj diff --git a/desktop/src-common/advent/action_test.clj b/desktop/src-common/advent/action_test.clj new file mode 100644 index 00000000..0abf0427 --- /dev/null +++ b/desktop/src-common/advent/action_test.clj @@ -0,0 +1,93 @@ +(ns advent.action-test) + +(defprotocol IAction + (begin [this state]) + (done? [this state]) + (continue [this state])) + + +(defmacro do-actions [name & forms] + `(vector ~@(for [form forms] + `(fn [~name] + ~form)))) + +(defn walk-to [who & targets ] + (for [[target-x target-y] targets] + (fn [state] + (reify + IAction + (begin [this state] (println "Starting Walking") state) + (continue [this {:keys [x y] :as state}] + (println "Continue Walking from" x y) + (Thread/sleep 500) + (assoc state :x (inc x) :y (inc y))) + (done? [this {:keys [x y]} ] + (and (= x target-x) + (= y target-y))))))) + +(defn talk [who text] + (reify + IAction + (begin [this state] + (println "Speaking:" text) + (assoc state :time 0)) + (continue [this state] + (Thread/sleep 200) + (assoc state :time (inc (:time state)))) + (done? [this {:keys [time]}] + (< 3 time)))) + +(defn give-item [item] + (reify + IAction + (begin [this state] + (println "Receiving item:" item) + (update-in state [:items] #(conj % item))) + (continue [this state] + state) + (done? [this state] + true))) + + +(defn walk-to [who & targets ] + (for [[target-x target-y] targets] + (fn [state] + (reify + IAction + (begin [this state] (println "Starting Walking to" target-x target-y) state) + (continue [this {:keys [x y] :as state}] + (println "Continue Walking from" x y) + (Thread/sleep 500) + (assoc state :x (inc x) :y (inc y))) + (done? [this {:keys [x y]} ] + (and (>= x target-x) + (>= y target-y))))))) + +(defn get-script [] + (let [random-loc (+ 3 (rand-int 10))] + (do-actions state + (if (= 1 (rand-int 2)) + (give-item :gold) + (give-item :candy)) + (walk-to :ego [3 3] [random-loc random-loc] ) + (if ((:items state) :gold) + (talk :ego "I have enough money to buy something") + (talk :ego "I'm broke."))))) + +(defn test-run [] + (let [state {:x 0 :y 0 :time 0 :items #{}} + actions (get-script)] + (loop [actions actions + state state + started? false] + (when (seq actions) + (let [step ((first actions) state)] + (if (sequential? step) + (recur (concat step (rest actions)) state false) + (let [state (if started? + state + (begin step state)) + state (continue step state)] + (if (done? step state) + (recur (rest actions) state false) + (recur actions state true)))))))))