 ;; Public Types
 ;; -----------------------------------------
 
-(s/def ::point ::board/coord)
+(s/def ::destination ::board/coord)
 (s/def ::taken (s/coll-of ::board/coord))
 (s/def ::winner ::player/player)
 (s/def ::looser ::player/playable-cell)
-(s/def ::conversion (s/keys :req-un [::point ::taken ::winner ::looser]))
-(s/def ::transition (s/every ::conversion))
+(s/def ::jump (s/keys :req-un [::destination ::taken ::winner ::looser]))
+(s/def ::transition (s/every ::jump))
 
 (s/def ::transitions
   (s/map-of ::player/player
-    (s/map-of ::board/coord ::transition)))
+    (s/map-of ::destination ::transition)))
 
 
 ;; -----------------------------------------

(defn- empty-cell-conversion
  "Create a move to take an empty cell"
  [player point]
  {:point point
   :winner player
   :looser :empty
   :taken [point]})

(defn- apply-conversion
  "Apply a move onto the board, yielding a new board"
  [board {:keys [winner taken]}]
  (reduce #(board/convert-cell %1 %2 winner) board taken))

(defn conversions->transition
  [conversions]
  (if-let [{:keys [winner point]} (first conversions)]
    (conj conversions (empty-cell-conversion winner point))
    conversions))

(defn- map-transition-tree
  [xf game-tree]

  [board]
  (let [aboard (board/board->array board)]
    (map-transition-tree
      add-destination
      (transduce
        (mapcat #(available-jumps-at aboard %))
        (algo/group-by-reducer :winner :destination)
        (board/empty-cells board)))))

(defn apply-transition
  [board transition]
  (reduce apply-jump board transition))

;; -----------------------------------------
;; TESTS
