mirror of
https://github.com/richardharrington/robotwar.git
synced 2024-05-28 23:41:31 +00:00
made shorter aliases (without 'robotwar.' prefix) for all namespaces
This commit is contained in:
parent
4af58b61ab
commit
54161691fa
|
@ -1,9 +1,10 @@
|
|||
(ns robotwar.brain
|
||||
(:use [clojure.string :only [join]]
|
||||
[clojure.pprint :only [pprint]])
|
||||
(:require (robotwar kernel-lexicon foundry)))
|
||||
(:require [robotwar.kernel-lexicon :as kernel-lexicon]
|
||||
[robotwar.foundry :as foundry]))
|
||||
|
||||
(def op-map (into {} (for [op robotwar.kernel-lexicon/op-commands]
|
||||
(def op-map (into {} (for [op kernel-lexicon/op-commands]
|
||||
[op (case op
|
||||
"/" #(int (Math/round (float (/ %1 %2))))
|
||||
"#" not=
|
||||
|
@ -14,14 +15,14 @@
|
|||
from the registers. takes a register and a world, and returns the
|
||||
result of running the register's read function on the world."
|
||||
[{read :read} world]
|
||||
(read world))
|
||||
(read world))
|
||||
|
||||
(defn write-register
|
||||
"a function to create a new world when the brain pushes data to a register.
|
||||
takes a register, a world, and data, and returns the result of running the
|
||||
register's write function on the data and the world."
|
||||
[{write :write} world data]
|
||||
(write world data))
|
||||
(write world data))
|
||||
|
||||
(defn init-brain
|
||||
"initialize the brain, meaning all the internal state variables that go along
|
||||
|
@ -31,7 +32,7 @@
|
|||
{:acc 0
|
||||
:instr-ptr 0
|
||||
:call-stack []
|
||||
:obj-code (robotwar.foundry/assemble src-code reg-names)})
|
||||
:obj-code (foundry/assemble src-code reg-names)})
|
||||
|
||||
(defn resolve-arg [{arg-val :val arg-type :type} registers labels world]
|
||||
"resolves an instruction argument to a numeric value
|
||||
|
@ -44,7 +45,7 @@
|
|||
|
||||
(defn step-brain
|
||||
"takes a robot and a world. returns a world.
|
||||
|
||||
|
||||
Only the brain (the internal state of the robot)
|
||||
will be different in the new world we pass back, for all of the operations
|
||||
except 'TO', which may also alter the external state of the robot, or the wider world.
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
(ns robotwar.core
|
||||
(:use [clojure.pprint])
|
||||
(:require (robotwar foundry brain robot world game-lexicon brain-test)))
|
||||
(:require [robotwar.foundry :as foundry]
|
||||
[robotwar.brain :as braini]
|
||||
[robotwar.robot :as robot]
|
||||
[robotwar.world :as world]
|
||||
[robotwar.game-lexicon :as game-lexicon]
|
||||
[robotwar.brain-test :as brain-test]))
|
||||
|
||||
; this is a hacky place for messing with stuff. currently imports
|
||||
; all the test data from brain-test, and the function below uses
|
||||
|
@ -14,19 +19,25 @@
|
|||
; their ugly full system-names of the read and write functions.) Very convenient.
|
||||
|
||||
(def get-robot (fn [world-tick-idx robot-idx]
|
||||
((:robots (robotwar.world/get-world
|
||||
((:robots (world/get-world
|
||||
world-tick-idx
|
||||
robot-idx
|
||||
robotwar.brain-test/worlds))
|
||||
brain-test/worlds))
|
||||
robot-idx)))
|
||||
|
||||
(def ppt (fn [world-tick-idx robot-idx & [reg-keys]]
|
||||
(let [{:keys [brain registers] :as robot} (get-robot world-tick-idx robot-idx)]
|
||||
(let [{:keys [brain registers] :as robot}
|
||||
(get-robot world-tick-idx robot-idx)]
|
||||
(pprint
|
||||
(into robot
|
||||
{:brain (assoc-in
|
||||
brain
|
||||
[:obj-code :instrs]
|
||||
(sort (zipmap (range) (get-in brain [:obj-code :instrs]))))
|
||||
:registers (sort (into {} (for [[reg-name reg-map] (select-keys registers reg-keys)]
|
||||
(sort (zipmap (range) (get-in
|
||||
brain
|
||||
[:obj-code :instrs]))))
|
||||
:registers (sort (into {} (for [[reg-name reg-map]
|
||||
(select-keys
|
||||
registers
|
||||
reg-keys)]
|
||||
{reg-name (:val reg-map)})))})))))
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
(ns robotwar.foundry
|
||||
(:require [robotwar.kernel-lexicon])
|
||||
(:require [robotwar.kernel-lexicon :as kernel-lexicon])
|
||||
(:use (clojure [string :only [split join]]
|
||||
[pprint :only [pprint]])
|
||||
[clojure.core.match :only [match]]))
|
||||
|
@ -22,7 +22,7 @@
|
|||
(map #(re-find #"[^;]*" %) lines))
|
||||
|
||||
(def lex-re
|
||||
(let [op-string (join robotwar.kernel-lexicon/op-commands)]
|
||||
(let [op-string (join kernel-lexicon/op-commands)]
|
||||
(re-pattern (str "[" op-string "]|[^" op-string "\\s]+"))))
|
||||
|
||||
(defn lex-line
|
||||
|
@ -48,7 +48,7 @@
|
|||
(catch Exception e nil)))
|
||||
|
||||
(defn valid-word
|
||||
"Capital letters and numbers, starting with a capital letter"
|
||||
"Capital letters and numbers, starting with a capital letter"
|
||||
[s]
|
||||
(re-matches #"^[A-Z][A-Z\d]*" s))
|
||||
|
||||
|
@ -62,7 +62,7 @@
|
|||
[{token-str :token-str :as token} reg-names]
|
||||
(let [parser-priority
|
||||
[[(set reg-names) :register]
|
||||
[(set robotwar.kernel-lexicon/commands) :command]
|
||||
[(set kernel-lexicon/commands) :command]
|
||||
[str->int :number]
|
||||
[valid-word :label]
|
||||
[return-err :error]]]
|
||||
|
@ -71,7 +71,7 @@
|
|||
(when-let [token-val (parser token-str)]
|
||||
(dissoc (into token {:val token-val, :type token-type})
|
||||
:token-str)))
|
||||
parser-priority)))
|
||||
parser-priority)))
|
||||
|
||||
(defn parse
|
||||
"take the tokens and convert them to structured source code ready for compiling.
|
||||
|
@ -99,8 +99,8 @@
|
|||
(and (= current-val "-")
|
||||
(= next-type :number)
|
||||
(not (#{:number :register} prev-type)))
|
||||
(recur (rest tail)
|
||||
(conj results (into current-token {:val (- next-val), :type :number})))
|
||||
(recur (rest tail)
|
||||
(conj results (into current-token {:val (- next-val), :type :number})))
|
||||
:otherwise (recur tail (conj results current-token))))))
|
||||
|
||||
(defn make-instr-pairs
|
||||
|
@ -115,12 +115,12 @@
|
|||
(if (empty? tokens)
|
||||
result
|
||||
(match [token]
|
||||
[{:type (:or :number :register)}]
|
||||
(recur tail (conj result [(into token {:val ",", :type :command}) token]))
|
||||
[(:or {:type :label} {:type :command, :val "ENDSUB"})]
|
||||
(recur tail (conj result [token nil]))
|
||||
[{:type :command}]
|
||||
(recur (rest tail) (conj result [token (first tail)]))))))
|
||||
[{:type (:or :number :register)}]
|
||||
(recur tail (conj result [(into token {:val ",", :type :command}) token]))
|
||||
[(:or {:type :label} {:type :command, :val "ENDSUB"})]
|
||||
(recur tail (conj result [token nil]))
|
||||
[{:type :command}]
|
||||
(recur (rest tail) (conj result [token (first tail)]))))))
|
||||
|
||||
; TODO: preserve :line and :pos metadata with labels,
|
||||
; when labels are transferred from the instruction list to the label map
|
||||
|
@ -148,9 +148,9 @@
|
|||
So far only parse implements error-checking."
|
||||
(let [parse-with-reg-names #(parse % reg-names)
|
||||
lexed (-> src-code split-lines strip-comments lex)]
|
||||
(reduce (fn [result step]
|
||||
(if (= (:type result) :error)
|
||||
result
|
||||
(step result)))
|
||||
lexed
|
||||
[parse-with-reg-names disambiguate-minus-signs make-instr-pairs map-labels])))
|
||||
(reduce (fn [result step]
|
||||
(if (= (:type result) :error)
|
||||
result
|
||||
(step result)))
|
||||
lexed
|
||||
[parse-with-reg-names disambiguate-minus-signs make-instr-pairs map-labels])))
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns robotwar.robot
|
||||
(:use [clojure.string :only [join]])
|
||||
(:require (robotwar brain game-lexicon)))
|
||||
(:require [robotwar.brain :as brain]
|
||||
[robotwar.game-lexicon :as game-lexicon]))
|
||||
|
||||
(defn init-register
|
||||
"takes a reg-name and a robot-idx (needed to locate the register in the world),
|
||||
|
@ -36,13 +37,13 @@
|
|||
[reg-name robot-idx field-name val]
|
||||
(init-register reg-name robot-idx
|
||||
(fn [world path-to-val]
|
||||
(field-name (get-robot world path-to-val)))
|
||||
(field-name (get-robot world path-to-val)))
|
||||
(fn [world _ _] world)
|
||||
val))
|
||||
|
||||
(defn init-registers
|
||||
[robot-idx attributes]
|
||||
(let [storage-registers (into {} (for [reg-name robotwar.game-lexicon/storage-reg-names]
|
||||
(let [storage-registers (into {} (for [reg-name game-lexicon/storage-reg-names]
|
||||
(init-default-register reg-name robot-idx)))]
|
||||
(into storage-registers
|
||||
[
|
||||
|
@ -53,12 +54,12 @@
|
|||
(letfn [(target-register [world path-to-val]
|
||||
(let [registers (get-registers world path-to-val)
|
||||
index-register (registers "INDEX")]
|
||||
(registers (robotwar.game-lexicon/reg-names (:val index-register)))))]
|
||||
(registers (game-lexicon/reg-names (:val index-register)))))]
|
||||
(init-register "DATA" robot-idx
|
||||
(fn [world path-to-val]
|
||||
(robotwar.brain/read-register (target-register world path-to-val) world))
|
||||
(brain/read-register (target-register world path-to-val) world))
|
||||
(fn [world path-to-val data]
|
||||
(robotwar.brain/write-register (target-register world) world data))
|
||||
(brain/write-register (target-register world) world data))
|
||||
0))
|
||||
|
||||
; RANDOM
|
||||
|
@ -87,7 +88,7 @@
|
|||
:accel-y 0
|
||||
:damage (:damage attributes)
|
||||
:registers (init-registers idx attributes)
|
||||
:brain (robotwar.brain/init-brain src-code robotwar.game-lexicon/reg-names)})
|
||||
:brain (brain/init-brain src-code game-lexicon/reg-names)})
|
||||
|
||||
(defn step-robot
|
||||
"takes a robot and a world and returns the new state of the world
|
||||
|
@ -97,5 +98,5 @@
|
|||
[robot world]
|
||||
(if (<= (:damage robot) 0)
|
||||
world
|
||||
(robotwar.brain/step-brain robot world)))
|
||||
(brain/step-brain robot world)))
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
(ns robotwar.world
|
||||
(:use [clojure.string :only [join]])
|
||||
(:require [robotwar.robot]))
|
||||
(:require [robotwar.robot :as robot]))
|
||||
|
||||
(defn init-world
|
||||
"initialize all the variables for a robot world."
|
||||
|
@ -9,9 +9,12 @@
|
|||
:height height
|
||||
:shells []
|
||||
:robots (vec (map-indexed (fn [idx program]
|
||||
(robotwar.robot/init-robot idx program {:pos-x (rand-int width)
|
||||
:pos-y (rand-int height)
|
||||
:damage 100}))
|
||||
(robot/init-robot
|
||||
idx
|
||||
program
|
||||
{:pos-x (rand-int width)
|
||||
:pos-y (rand-int height)
|
||||
:damage 100}))
|
||||
programs))
|
||||
:robot-idx 0})
|
||||
|
||||
|
@ -22,7 +25,7 @@
|
|||
each robot. Because otherwise, do we step the shells after every
|
||||
single robot has their turn?"
|
||||
[{:keys [robots robot-idx] :as world}]
|
||||
(assoc (robotwar.robot/step-robot (robots robot-idx) world)
|
||||
(assoc (robot/step-robot (robots robot-idx) world)
|
||||
:robot-idx
|
||||
(mod (inc robot-idx) (count robots))))
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(ns robotwar.brain-test
|
||||
(:use [clojure.test]
|
||||
[robotwar.brain])
|
||||
(:require [robotwar.world]))
|
||||
(:require [robotwar.world :as world]))
|
||||
|
||||
(def src-codes [ ; program 0: multi-use program
|
||||
" START
|
||||
|
@ -26,36 +26,36 @@
|
|||
1 TO INDEX
|
||||
DATA " ])
|
||||
|
||||
(def initial-world (robotwar.world/init-world 256 256 src-codes))
|
||||
(def worlds (iterate robotwar.world/tick-world initial-world))
|
||||
(def initial-world (world/init-world 256 256 src-codes))
|
||||
(def worlds (iterate world/tick-world initial-world))
|
||||
|
||||
(deftest branching-test
|
||||
(testing "comparison statement should cause jump in instr-ptr"
|
||||
(is (= (get-in (robotwar.world/get-world 4 0 worlds) [:robots 0 :brain :instr-ptr])
|
||||
(is (= (get-in (world/get-world 4 0 worlds) [:robots 0 :brain :instr-ptr])
|
||||
5))))
|
||||
|
||||
(deftest arithmetic-test
|
||||
(testing "addition"
|
||||
(is (= (get-in (robotwar.world/get-world 7 0 worlds) [:robots 0 :brain :acc])
|
||||
(is (= (get-in (world/get-world 7 0 worlds) [: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 (robotwar.world/get-world 5 0 worlds) [:robots 0 :brain])]
|
||||
(get-in (world/get-world 5 0 worlds) [:robots 0 :brain])]
|
||||
(= [instr-ptr call-stack]
|
||||
[9 [6]])))))
|
||||
|
||||
(deftest endsub-test
|
||||
(testing "endsub pops instr-ptr off call stack and goes there"
|
||||
(is (let [{:keys [instr-ptr call-stack]}
|
||||
(get-in (robotwar.world/get-world 9 0 worlds) [:robots 0 :brain])]
|
||||
(get-in (world/get-world 9 0 worlds) [:robots 0 :brain])]
|
||||
(= [instr-ptr call-stack]
|
||||
[6 []])))))
|
||||
|
||||
(deftest push-test
|
||||
(testing "pushing number to register"
|
||||
(is (= (get-in (robotwar.world/get-world 8 0 worlds) [:robots 0 :registers "A" :val])
|
||||
(is (= (get-in (world/get-world 8 0 worlds) [:robots 0 :registers "A" :val])
|
||||
1))))
|
||||
|
||||
;(deftest random-test
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
(:use (clojure [string :only [join]]
|
||||
[test])
|
||||
[robotwar.foundry])
|
||||
(:require [robotwar.game-lexicon]))
|
||||
(:require [robotwar.game-lexicon :as game-lexicon]))
|
||||
|
||||
(def line1 "IF DAMAGE # D GOTO MOVE ; comment or something")
|
||||
(def line2 "AIM-17 TO AIM ; other comment")
|
||||
|
@ -212,47 +212,47 @@
|
|||
|
||||
(deftest parse-token-register
|
||||
(testing "parsing register token"
|
||||
(is (= (parse-token {:token-str "AIM"} robotwar.game-lexicon/reg-names)
|
||||
(is (= (parse-token {:token-str "AIM"} game-lexicon/reg-names)
|
||||
{:val "AIM", :type :register}))))
|
||||
|
||||
(deftest parse-token-command-word
|
||||
(testing "parsing command token (word)"
|
||||
(is (= (parse-token {:token-str "GOTO"} robotwar.game-lexicon/reg-names)
|
||||
(is (= (parse-token {:token-str "GOTO"} game-lexicon/reg-names)
|
||||
{:val "GOTO", :type :command}))))
|
||||
|
||||
(deftest parse-token-command-operator
|
||||
(testing "parsing command token (operator)"
|
||||
(is (= (parse-token {:token-str "#"} robotwar.game-lexicon/reg-names)
|
||||
(is (= (parse-token {:token-str "#"} game-lexicon/reg-names)
|
||||
{:val "#", :type :command}))))
|
||||
|
||||
(deftest parse-token-number
|
||||
(testing "parsing number token"
|
||||
(is (= (parse-token {:token-str "-17"}robotwar.game-lexicon/reg-names)
|
||||
{:val -17, :type :number}))))
|
||||
(is (= (parse-token {:token-str "-17"}game-lexicon/reg-names)
|
||||
{:val -17, :type :number}))))
|
||||
|
||||
(deftest parse-token-label
|
||||
(testing "parsing label token"
|
||||
(is (= (parse-token {:token-str "SCAN"} robotwar.game-lexicon/reg-names)
|
||||
(is (= (parse-token {:token-str "SCAN"} game-lexicon/reg-names)
|
||||
{:val "SCAN", :type :label}))))
|
||||
|
||||
(deftest parse-token-error
|
||||
(testing "parsing error token"
|
||||
(is (= (parse-token {:token-str "-GOTO"} robotwar.game-lexicon/reg-names)
|
||||
(is (= (parse-token {:token-str "-GOTO"} game-lexicon/reg-names)
|
||||
{:val "Invalid word or symbol", :type :error}))))
|
||||
|
||||
(deftest parse-tokens-minus-sign
|
||||
(testing "parsing tokens with a binary minus sign"
|
||||
(is (= (parse lexed-tokens2 robotwar.game-lexicon/reg-names)
|
||||
(is (= (parse lexed-tokens2 game-lexicon/reg-names)
|
||||
parsed-tokens2))))
|
||||
|
||||
(deftest parse-tokens-negative-sign
|
||||
(testing "parsing tokens with a unary negative sign"
|
||||
(is (= (parse lexed-tokens3 robotwar.game-lexicon/reg-names)
|
||||
(is (= (parse lexed-tokens3 game-lexicon/reg-names)
|
||||
parsed-tokens3))))
|
||||
|
||||
(deftest parse-tokens-error
|
||||
(testing "parsing tokens with an invalid operator"
|
||||
(is (= (parse lexed-tokens4 robotwar.game-lexicon/reg-names)
|
||||
(is (= (parse lexed-tokens4 game-lexicon/reg-names)
|
||||
parsed-tokens4))))
|
||||
|
||||
(def minus-sign-disambiguated-tokens2 parsed-tokens2)
|
||||
|
@ -294,17 +294,17 @@
|
|||
|
||||
(deftest assemble-test-success
|
||||
(testing "compiling successfully"
|
||||
(is (= (assemble (join "\n" [line1 line2 line3]) robotwar.game-lexicon/reg-names)
|
||||
(is (= (assemble (join "\n" [line1 line2 line3]) game-lexicon/reg-names)
|
||||
multi-line-assembled))))
|
||||
|
||||
(deftest assemble-test-failure
|
||||
(testing "assemble results in error"
|
||||
(is (= (assemble (join "\n" [line1 line2 line3 line4]) robotwar.game-lexicon/reg-names)
|
||||
(is (= (assemble (join "\n" [line1 line2 line3 line4]) game-lexicon/reg-names)
|
||||
multi-line-assembled-error))))
|
||||
|
||||
(deftest preserving-line-and-pos-metadata-test
|
||||
(testing "line and pos metadata preserved through assembly process"
|
||||
(is (= (meta (get-in (assemble (join "\n" [line1 line2 line3]) robotwar.game-lexicon/reg-names)
|
||||
(is (= (meta (get-in (assemble (join "\n" [line1 line2 line3]) game-lexicon/reg-names)
|
||||
[:instrs 8 1]))
|
||||
{:line 3, :pos 14}))))
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user