94 lines
2.7 KiB
Clojure
94 lines
2.7 KiB
Clojure
(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)))))))))
|