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 77f52915d2

View File

@ -20,73 +20,80 @@
(defn path-to-val [robot-idx reg-name]
[:robots robot-idx :registers reg-name :val])
(defprotocol IRegister
(read-register [this world])
(defprotocol IReadRegister
"returns the value of a register"
(read-register [this world]))
(defprotocol IWriteRegister
"returns a world"
(write-register [this world data]))
(defrecord StorageRegister [robot-idx reg-name val]
IRegister
(read-register
"returns value stored in register"
[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)))
(def default-read-mixin
; returns :val field of register
{:read-register (fn [this world]
(:val this))})
(defrecord ReadOnlyRegister [robot-idx field-name]
IRegister
(read-register
"returns the value in a particular robot field"
[this world]
(get-in world (conj (path-to-robot robot-idx) field-name)))
(write-register
"has no effect (returns the world it was given)"
[this world data]
world))
(def default-write-mixin
; returns a world with :val field of register altered
{:write-register (fn [this world data]
(assoc-in world
(path-to-val (:robot-idx this) (:reg-name this))
data))})
(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 (:robot-idx 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"
[world robot-idx index-reg-name]
(let [registers (get-in world (path-to-registers robot-idx))]
(registers (reg-names (read-register (registers index-reg-name) world)))))
(defrecord DataRegister [robot-idx index-reg-name]
IRegister
IReadRegister
(read-register
"returns the number stored in whatever register
is pointed to by the index-reg-name register"
; returns the number stored in whatever register
; is pointed to by the index-reg-name register
[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
"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"
; 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
[this world data]
(write-register (target-register world robot-idx index-reg-name) world data)))
; TODO: (defrecord RandomRegister [robot-idx reg-name max-rand])
(write-register (get-target-register world robot-idx index-reg-name) world data)))
; TODO: (defrecord ShotRegister [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
"AIM, INDEX, SPEEDX and SPEEDY.
AIM and INDEX's specialized behaviors are only when they're used by
@ -104,7 +111,7 @@
{"Y" (->ReadOnlyRegister robot-idx :pos-y)}
{"DAMAGE" (->ReadOnlyRegister robot-idx :damage)}
{"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: {"RADAR" (->RadarRegister robot-idx "RADAR")}
]))))