added a spike for scripting using macros.

This commit is contained in:
=
2014-09-12 17:54:57 -07:00
parent aa5cb1f2f7
commit 60c1ac2ca3

View File

@@ -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)))))))))