     [cljs.spec :as s :include-macros true]
     [triboard.ai.scoring :as scoring]
     [triboard.logic.game :as game]
-    [triboard.logic.player :as player]
     [triboard.logic.scores :as scores]
     [triboard.logic.turn :as turn]
     ))

(defn- make-ai
  [board player]
  {:player player
   :other-players (remove #{player} player/all)
   :cell-weights (scoring/get-weighting board)
   })

(defn- score-move
  "Compute the strength of a move, based on the converted cells"
  [{:keys [player cell-weights]} transition]
  (reduce                                                   ;; TODO - Factor in move
    #(scores/update-scores-with %1 %2 cell-weights)
    scores/null-scores
    transition))

;; -----------------------------------------
;; Attempts game - tree (later minimax decoupled)
;; -----------------------------------------

(defn build-game-tree
  [game depth]
  (if (= 0 depth)
    game
    (let [transitions (turn/player-transitions (game/current-turn game))
          next-games (map #(game/play-move game (first %)) transitions)]
      (map vector
        transitions
        (map #(build-game-tree % (dec depth)) next-games)))
    ))

(defn test-build-game-tree
  []
  (let [init-game (game/new-game)]
    (build-game-tree init-game 1)))

;; -----------------------------------------
;; Attempts minimax
;; -----------------------------------------

;; TODO - How to add the custom scoring? How to keep the game? (use keys)
;; TODO - Use mapmin from http://worrydream.com/refs/Hughes-WhyFunctionalProgrammingMatters.pdf
;; TODO - Sort by scores as well


(defn contains-lower-value?
  [coll pot]
  (cond
    (empty? coll) false
    (<= (first coll) pot) true
    :else (recur (rest coll) pot)
    ))

(defn map-min-impl
  [max-min-val coll]
  (cond
    (empty? coll) max-min-val
    (contains-lower-value? (first coll) max-min-val) max-min-val ;; Will depend on player
    :else (recur
            (max max-min-val (apply min (first coll)))      ;; Will depend on player
            (rest coll))
    ))

(defn map-min
  [coll]
  (map-min-impl (min (first coll)) (rest coll)))

;; -----------------------------------------


    ))

;; -----------------------------------------
;; Public API
;; -----------------------------------------

