               (int \D) {:rotation turn-speed}
               (int \W) {:acceleration 1}
               (int \K) {:shoot true}
-              (int \R) {:reset true}
+              (int \R) {:repair true}
               (int \1) {:set-level 1}
               (int \2) {:set-level 2}
               (int \3) {:set-level 3}

                :shots shots))
  )

(defmulti move (fn [object] (:type object)))

(defmethod move :ship [{:keys [direction rotation-speed position speed acceleration shots] :as ship}]
  (let [direction (+ direction (* rotation-speed turn-millis 0.001))
        speed (vec+vec speed (rotate-vec direction [0 (* acceleration turn-millis 0.001)]))
        [x y] (vec+vec speed position)
        position [(mod x width) (mod y height)]
        shots (->> shots
                   (filter #(not (out-of-bounds? %)))
                   (map move))]
    (assoc ship :direction direction
                :speed speed
                :position position
                :shots shots)))

(defmethod move :shot [{:keys [position speed] :as shot}]
  (let [position (vec+vec speed position)]
    (assoc shot :position position)))

(defmethod move :asteroid [{:keys [direction rotation-speed position speed] :as asteroid}]
  (let [direction (+ direction (* rotation-speed turn-millis 0.001))
        [x y] (vec+vec speed position)
        position [(mod x width) (mod y height)]]
    (assoc asteroid :direction direction
                    :position position)))

(defmethod move :debris [{:keys [life-time direction rotation-speed position speed size] :as debris}]
  (if (<= life-time 0)
    nil
    (let [direction (+ direction (* rotation-speed turn-millis 0.001))
          [x y] (vec+vec speed position)
          position [(mod x width) (mod y height)]
          size (* size (- 1 (/ turn-millis life-time)))
          life-time (- life-time turn-millis)]
      (assoc debris :direction direction
                      :position position
                      :size size
                      :life-time life-time))))

(defn move-many [coll]
  (->> coll
       (map move)
       (filter (comp not nil?))))

; Accelerating shots - not used right now
#_(defmethod move :shot [{:keys [position speed direction acceleration] :as shot}]
    (let [speed (vec+vec speed (rotate-vec direction [0 (* acceleration turn-millis 0.001)]))
          position (vec+vec speed position)]
      (assoc shot :speed speed
                  :position position)))

(defn turn [{:keys [rotation-speed] :as ship} rot]
  (assoc ship :rotation-speed (+ rotation-speed rot)))

(defn create-asteroids
  ([num size] (map create-asteroid (repeat num size)))
  ([num size pos speed] (map create-asteroid (repeat num size) (repeat num pos) (repeat num speed)))
  #_(repeat num (create-asteroid size pos speed)))

(defn out-of-bounds? [{[x y] :position size :size}]
  (or
