added a spike for scripting using macros.
This commit is contained in:
93
desktop/src-common/advent/action_test.clj
Normal file
93
desktop/src-common/advent/action_test.clj
Normal 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)))))))))
|
||||
Reference in New Issue
Block a user