                                     ::weapon]))
 
 (s/def ::world-size ::position)
-(s/def ::terrain (s/map-of ::position ::character))
-(s/def ::player-pos ::position)
+(s/def ::terrain (s/map-of ::position ::character :min-count 1))
 
 (s/def ::game (s/keys :req-un [::world-size
-                               ::terrain
-                               ::player-pos]))
+                               ::terrain]))
 
 (s/def ::player-action (conj (s/describe ::direction) :fire))
 

(defn- terrain-accessible? [terrain pos]
  (not (contains? terrain pos)))

(defn- damage-terrain [terrain target attack]
  (if-let [health (get-in terrain [target :health])]
    (let [new-health (- health attack)]

;;
(def player-default-health 10)

(defn- is-player? [terrain]
  (= (:type terrain) :player))

(defn player-position [game]
  (first (reduce-kv #(if (is-player? %3) (conj %1 %2) %1)
                    []
                    (:terrain game))))

(defn player-health [{terrain :terrain :as game}]
  (get-in terrain [(player-position game) :health]))

(defn player-direction [{terrain :terrain :as game}]
  (get-in terrain [(player-position game) :direction]))

(defn configure-player-weapon [game overrides]
  (update-in game [:terrain (player-position game) :weapon] merge overrides))

(defn set-player
  ([game new-pos] (set-player game new-pos :up))
  ([game new-pos direction]
   (-> game
       (update :terrain dissoc (player-position game))
       (assoc-in [:terrain new-pos] (-> (make-terrain :player)
                                        (assoc :health player-default-health)
                                        (assoc :weapon (make-weapon :dagger))
                                        (set-terrain-direction direction))))))

(defn- player-attack [{terrain :terrain :as game} player-pos]
  (reduce (fn [game counter]
            (let [target-pos (get-position player-pos (player-direction game) counter)]
              (update game :terrain attack-target player-pos target-pos :zombie)))
          game
          (range 1 (inc (weapon-range (get-in terrain [player-pos :weapon]))))))

(defn run-player-action [{world-size :world-size :as game} player-action]
  (if-let [player-position (player-position game)]
    (if (= :fire player-action)
      (player-attack game player-position)
      (update game :terrain move-terrain
              player-position
              player-action
              world-size))
    game))

;;
;; zombie
