added 'random' record to register, switched to mixin system for most records, got all existing tests working

This commit is contained in:
Richard Harrington 2013-08-08 23:24:59 -04:00
parent 74ab6affe3
commit abbc60d81c

View File

@ -20,73 +20,80 @@
(defn path-to-val [robot-idx reg-name] (defn path-to-val [robot-idx reg-name]
[:robots robot-idx :registers reg-name :val]) [:robots robot-idx :registers reg-name :val])
(defprotocol IRegister (defprotocol IReadRegister
(read-register [this world]) "returns the value of a register"
(read-register [this world]))
(defprotocol IWriteRegister
"returns a world"
(write-register [this world data])) (write-register [this world data]))
(defrecord StorageRegister [robot-idx reg-name val] (def default-read-mixin
IRegister ; returns :val field of register
(read-register {:read-register (fn [this world]
"returns value stored in register" (:val this))})
[this world]
val)
(write-register
"returns world with value in register altered"
[this world data]
(assoc-in world (path-to-val robot-idx reg-name) data)))
(defrecord ReadOnlyRegister [robot-idx field-name] (def default-write-mixin
IRegister ; returns a world with :val field of register altered
(read-register {:write-register (fn [this world data]
"returns the value in a particular robot field" (assoc-in world
[this world] (path-to-val (:robot-idx this) (:reg-name this))
(get-in world (conj (path-to-robot robot-idx) field-name))) data))})
(write-register
"has no effect (returns the world it was given)"
[this world data]
world))
(defn target-register (def robot-field-read-mixin
; returns the value of a field in the robot hash-map
{:read-register (fn [this world]
(get-in world (conj path-to-robot (:field-name this))))})
(def no-op-write-mixin
; returns a world with nothing changed
{:write-register (fn [this world data]
world)})
(def random-read-mixin
; returns a random number. maximum value is the :val field of the register
{:read-register (fn [this world]
(rand-int (:val this)))})
(defrecord StorageRegister [robot-idx reg-name val])
(extend StorageRegister
IReadRegister default-read-mixin
IWriteRegister default-write-mixin)
(defrecord ReadOnlyRegister [robot-idx field-name])
(extend ReadOnlyRegister
IReadRegister robot-field-read-mixin
IWriteRegister no-op-write-mixin)
(defrecord RandomRegister [robot-idx reg-name val])
(extend RandomRegister
IReadRegister random-read-mixin
IWriteRegister default-write-mixin)
(defn get-target-register
"helper function for DataRegister record" "helper function for DataRegister record"
[world robot-idx index-reg-name] [world robot-idx index-reg-name]
(let [registers (get-in world (path-to-registers robot-idx))] (let [registers (get-in world (path-to-registers robot-idx))]
(registers (reg-names (read-register (registers index-reg-name) world))))) (registers (reg-names (read-register (registers index-reg-name) world)))))
(defrecord DataRegister [robot-idx index-reg-name] (defrecord DataRegister [robot-idx index-reg-name]
IRegister IReadRegister
(read-register (read-register
"returns the number stored in whatever register ; returns the number stored in whatever register
is pointed to by the index-reg-name register" ; is pointed to by the index-reg-name register
[this world] [this world]
(read-register (target-register world robot-idx index-reg-name) world)) (read-register (get-target-register world robot-idx index-reg-name) world))
IWriteRegister
(write-register (write-register
"returns a world with the number in the register pointed to ; returns a world with the number in the register pointed to
by the index-reg-name register updated with the data argument to write-register" ; by the index-reg-name register updated with the data argument to write-register
[this world data] [this world data]
(write-register (target-register world robot-idx index-reg-name) world data))) (write-register (get-target-register world robot-idx index-reg-name) world data)))
; TODO: (defrecord RandomRegister [robot-idx reg-name max-rand])
; TODO: (defrecord ShotRegister [robot-idx reg-name]) ; TODO: (defrecord ShotRegister [robot-idx reg-name])
; TODO: (defrecord RadarRegister [robot-idx reg-name]) ; TODO: (defrecord RadarRegister [robot-idx reg-name])
; ; RANDOM
; (init-register "RANDOM" robot-idx
; (fn [world path-to-val]
; (rand-int (get-in world path-to-val)))
; assoc-in
; 0)
;
; ; X and Y and DAMAGE
; (init-read-only-register "X" robot-idx :pos-x (:pos-x attributes))
; (init-read-only-register "Y" robot-idx :pos-y (:pos-y attributes))
; (init-read-only-register "DAMAGE" robot-idx :damage (:damage attributes))])))
;
; ; TODO: SHOT AND RADAR
(defn init-registers (defn init-registers
"AIM, INDEX, SPEEDX and SPEEDY. "AIM, INDEX, SPEEDX and SPEEDY.
AIM and INDEX's specialized behaviors are only when they're used by AIM and INDEX's specialized behaviors are only when they're used by
@ -104,7 +111,7 @@
{"Y" (->ReadOnlyRegister robot-idx :pos-y)} {"Y" (->ReadOnlyRegister robot-idx :pos-y)}
{"DAMAGE" (->ReadOnlyRegister robot-idx :damage)} {"DAMAGE" (->ReadOnlyRegister robot-idx :damage)}
{"DATA" (->DataRegister robot-idx "INDEX")} {"DATA" (->DataRegister robot-idx "INDEX")}
; TODO: {"RANDOM" (->RandomRegister robot-idx "RANDOM" 0)} {"RANDOM" (->RandomRegister robot-idx "RANDOM" 0)}
; TODO: {"SHOT" (->ShotRegister robot-idx "SHOT")} ; TODO: {"SHOT" (->ShotRegister robot-idx "SHOT")}
; TODO: {"RADAR" (->RadarRegister robot-idx "RADAR")} ; TODO: {"RADAR" (->RadarRegister robot-idx "RADAR")}
])))) ]))))