mirror of
https://github.com/richardharrington/robotwar.git
synced 2024-06-09 08:29:32 +00:00
now only stores last world in each round when building simulation
also did significant refactoring, including changing variable names from 'round' to 'combined-world' before going through the simulation-pass, and 'sim-world' afterwards. Soon, we'll make the worlds coming out of 'sim-world' a lot less verbose.
This commit is contained in:
parent
9ab14a7653
commit
a1df709c4f
|
@ -5,16 +5,13 @@
|
|||
(:require [clj-time.core :as time]
|
||||
[clj-time.periodic :as periodic]))
|
||||
|
||||
(defn build-simulation-rounds [worlds fast-forward]
|
||||
(let [round-duration (/ *GAME-SECONDS-PER-TICK* fast-forward)
|
||||
num-robots (count (:robots (nth worlds 0)))
|
||||
rounds (partition num-robots worlds)]
|
||||
;(println round-duration num-robots (nth rounds 0))
|
||||
(map-indexed (fn [idx worlds]
|
||||
{:worlds worlds
|
||||
(defn build-sim-worlds [combined-worlds fast-forward]
|
||||
(let [tick-duration (/ *GAME-SECONDS-PER-TICK* fast-forward)]
|
||||
(map-indexed (fn [idx combined-world]
|
||||
{:sim-world combined-world
|
||||
:idx idx
|
||||
:timestamp (int (* idx round-duration 1000))})
|
||||
rounds)))
|
||||
:timestamp (int (* idx tick-duration 1000))})
|
||||
combined-worlds)))
|
||||
|
||||
(defn near-point [[pos-x pos-y] [x y]]
|
||||
(and (= (int pos-x) x)
|
||||
|
@ -41,43 +38,42 @@
|
|||
"\n"
|
||||
header-footer)))
|
||||
|
||||
(defn display-robots-info [world]
|
||||
(doseq [robot-idx (range (count (:robots world)))]
|
||||
(defn display-robots-info [sim-world idx fps]
|
||||
(doseq [robot-idx (range (count (:robots sim-world)))]
|
||||
(println (apply format
|
||||
"%d: x %.1f, y %.1f, v-x %.1f, v-y %.1f, desired-v-x %.1f, desired-v-y %.1f"
|
||||
(map #(get-in world [:robots robot-idx %])
|
||||
[:idx :pos-x :pos-y :v-x :v-y :desired-v-x :desired-v-y])))))
|
||||
(map #(get-in sim-world [:robots robot-idx %])
|
||||
[:idx :pos-x :pos-y :v-x :v-y :desired-v-x :desired-v-y]))))
|
||||
(println (format "Animation frame rate: %.1f frames per second", fps))
|
||||
(println "Round number:" idx)
|
||||
(println (format "Seconds elapsed in the game-world: %.1f", (* idx *GAME-SECONDS-PER-TICK*)))
|
||||
(println))
|
||||
|
||||
(defn animate
|
||||
"takes a simulation and animates it."
|
||||
[initial-simulation-rounds print-width print-height fps]
|
||||
[initial-sim-worlds print-width print-height fps]
|
||||
(let [frame-period (time/millis (* (/ 1 fps) 1000))
|
||||
starting-instant (time/now)]
|
||||
(loop [[{:keys [worlds idx]} :as rounds] initial-simulation-rounds
|
||||
(loop [[{:keys [sim-world idx]} :as sim-worlds] initial-sim-worlds
|
||||
frame-start starting-instant]
|
||||
(doseq [world worlds]
|
||||
(println (arena-text-grid world print-width print-height))
|
||||
(display-robots-info world)
|
||||
(println (format "Animation frame rate: %.1f frames per second", fps))
|
||||
(println "Round number:" idx)
|
||||
(println (format "Seconds elapsed in the game-world: %.1f", (* idx *GAME-SECONDS-PER-TICK*)))
|
||||
(println))
|
||||
|
||||
(let [desired-next-frame-start (time/plus frame-start frame-period)
|
||||
(println (arena-text-grid sim-world print-width print-height))
|
||||
(display-robots-info sim-world idx fps)
|
||||
(let [desired-next-frame-calc-start (time/plus frame-start frame-period)
|
||||
this-instant (time/now)
|
||||
next-frame-start (if (time/after? this-instant desired-next-frame-start)
|
||||
this-instant
|
||||
(do
|
||||
(Thread/sleep (time/in-msecs (time/interval
|
||||
this-instant
|
||||
desired-next-frame-start)))
|
||||
desired-next-frame-start))
|
||||
next-frame-calc-start (if (time/after? this-instant desired-next-frame-calc-start)
|
||||
this-instant
|
||||
(do
|
||||
(-> (time/interval
|
||||
this-instant
|
||||
desired-next-frame-calc-start)
|
||||
(time/in-msecs)
|
||||
(Thread/sleep))
|
||||
desired-next-frame-calc-start))
|
||||
animation-timestamp (time/in-msecs (time/interval
|
||||
starting-instant
|
||||
next-frame-start))]
|
||||
(recur (drop-while (fn [round]
|
||||
(< (:timestamp round) animation-timestamp))
|
||||
rounds)
|
||||
next-frame-start)))))
|
||||
next-frame-calc-start))]
|
||||
(recur (drop-while #(< (:timestamp %) animation-timestamp)
|
||||
sim-worlds)
|
||||
next-frame-calc-start)))))
|
||||
|
||||
|
||||
|
|
|
@ -15,12 +15,12 @@
|
|||
|
||||
(defn world []
|
||||
(world/init-world 256.0 256.0 (progs)))
|
||||
(defn worlds []
|
||||
(iterate world/tick-world (world)))
|
||||
(defn simulation-rounds []
|
||||
(animate/build-simulation-rounds (worlds) 25))
|
||||
(defn combined-worlds []
|
||||
(world/build-combined-worlds (world)))
|
||||
(defn sim-worlds []
|
||||
(animate/build-sim-worlds (combined-worlds) 25))
|
||||
(defn make-it-so []
|
||||
(animate/animate (simulation-rounds) 25 25 20.0))
|
||||
(animate/animate (sim-worlds) 25 25 20.0))
|
||||
|
||||
(def rr register/read-register)
|
||||
(def wr register/write-register)
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
(GET "/" [] "Hello World, Welcome to Robotwar.")
|
||||
(GET "/json-test" [] (response/response {:foo 6 :bar 8}))
|
||||
(GET "/programs" [] (response/response test-programs/programs))
|
||||
(GET "/simulations" [] (response/response (take 1 (core/simulation-rounds))))
|
||||
(GET "/simulations" [] (response/response (take 1 (core/sim-worlds))))
|
||||
(route/resources "/")
|
||||
(route/not-found "Not Found"))
|
||||
|
||||
|
|
|
@ -18,25 +18,13 @@
|
|||
:pos-y (rand height)
|
||||
:aim 0.0
|
||||
:damage 100.0}))
|
||||
programs))
|
||||
:robot-idx 0})
|
||||
programs))})
|
||||
|
||||
(defn tick-world
|
||||
"TODO: fill this out quite a bit. Dealing with shells, for instance.
|
||||
We might want to change this to a system where we count by whole rounds
|
||||
(where each robot gets to go) rather than just a stream of worlds, one for
|
||||
each robot. Because otherwise, do we step the shells after every
|
||||
single robot has their turn?"
|
||||
[{:keys [robots robot-idx] :as world}]
|
||||
(assoc (robot/step-robot (robots robot-idx) world)
|
||||
:robot-idx
|
||||
(mod (inc robot-idx) (count robots))))
|
||||
(defn tick-combined-world
|
||||
[starting-world]
|
||||
(reduce (fn [{robots :robots :as world} robot-idx]
|
||||
(robot/step-robot (robots robot-idx) world))
|
||||
starting-world
|
||||
(range (count (:robots starting-world)))))
|
||||
|
||||
(defn get-world
|
||||
"convenience function for identifying a world in a sequence of worlds
|
||||
by its round idx (where one round means all the robots have stepped)
|
||||
and its robot idx."
|
||||
[round-idx robot-idx worlds]
|
||||
(let [num-robots (count (:robots (nth worlds 0)))
|
||||
world-idx (+ (* round-idx num-robots) robot-idx)]
|
||||
(nth worlds world-idx)))
|
||||
(def build-combined-worlds (partial iterate tick-combined-world))
|
||||
|
|
|
@ -9,24 +9,24 @@
|
|||
(def initial-world
|
||||
(world/init-world 256.0 256.0 [(:multi-use test-programs/programs)]))
|
||||
|
||||
(def worlds (iterate world/tick-world initial-world))
|
||||
(def combined-worlds (world/build-combined-worlds initial-world))
|
||||
|
||||
(deftest branching-test
|
||||
(testing "comparison statement should cause jump in instr-ptr"
|
||||
(is (= (get-in (world/get-world 4 0 worlds)
|
||||
(is (= (get-in (nth combined-worlds 4)
|
||||
[:robots 0 :brain :instr-ptr])
|
||||
5))))
|
||||
|
||||
(deftest arithmetic-test
|
||||
(testing "addition"
|
||||
(is (= (get-in (world/get-world 7 0 worlds)
|
||||
(is (= (get-in (nth combined-worlds 7)
|
||||
[:robots 0 :brain :acc])
|
||||
1))))
|
||||
|
||||
(deftest gosub-test
|
||||
(testing "gosub should move instr-ptr and add the return-ptr to the call stack"
|
||||
(is (let [{:keys [instr-ptr call-stack]}
|
||||
(get-in (world/get-world 5 0 worlds)
|
||||
(get-in (nth combined-worlds 5)
|
||||
[:robots 0 :brain])]
|
||||
(= [instr-ptr call-stack]
|
||||
[9 [6]])))))
|
||||
|
@ -34,13 +34,13 @@
|
|||
(deftest endsub-test
|
||||
(testing "endsub pops instr-ptr off call stack and goes there"
|
||||
(is (let [{:keys [instr-ptr call-stack]}
|
||||
(get-in (world/get-world 9 0 worlds)
|
||||
(get-in (nth combined-worlds 9)
|
||||
[:robots 0 :brain])]
|
||||
(= [instr-ptr call-stack]
|
||||
[6 []])))))
|
||||
|
||||
(deftest push-test
|
||||
(testing "pushing number to register"
|
||||
(is (= (get-in (world/get-world 8 0 worlds)
|
||||
(is (= (get-in (nth combined-worlds 8)
|
||||
[:robots 0 :brain :registers "A" :val])
|
||||
1))))
|
||||
|
|
Loading…
Reference in New Issue
Block a user