 (defn negamax
   ""
   [is-first-player state got-time? grid-width grid-height ret-chan]
-  (loop
-      [deepness 1]
-
-    (if (and @got-time? (< deepness 10))
-      (let [point (negamax-inner state
-                               Double/NEGATIVE_INFINITY
-                               Double/POSITIVE_INFINITY
-                               got-time?
-                               is-first-player
-                               deepness         ; Steps
-                               grid-width grid-height)]
-        (when (not (empty? (point :best-move)))
-          (async/>!! ret-chan point))
-        (recur (inc deepness))))))
+  (try
+    (loop
+        [deepness 1]
+      (prn "deepness" deepness @got-time?)
+      (if (and @got-time?)
+        (let [point (negamax-inner state
+                                   Double/NEGATIVE_INFINITY
+                                   Double/POSITIVE_INFINITY
+                                   got-time?
+                                   is-first-player
+                                   deepness                 ; Steps
+                                   deepness
+                                   grid-width grid-height)]
+          (when (not (empty? (point :best-move)))
+            (async/>!! ret-chan point))
+          (recur (inc deepness)))
+
+        nil))
+    (catch TimeoutException e (prn "done"))
+
+  ))
 
 (defn -getNextMove
   "Gets the next best move"
   [charmat timeout]
   (let [ret-chan (async/chan (async/sliding-buffer 1))
-        timeout-chan (async/timeout (- timeout 5))
+        timeout-chan (async/timeout (- timeout 10))
         got-time? (atom true)
         charmat-seq (lazy-seq charmat)
         state (gen-map-from-charmat charmat-seq {true #{} false #{}} 0)

  (or (= Double/POSITIVE_INFINITY (state :heuristic-result))
      (= Double/NEGATIVE_INFINITY (state :heuristic-result))))


(defn- is-it-a-win?
  ""
  [grid-w grid-h state]
  (let [point (state :last-move)
        max-lines ((state :lines) :max)
        min-lines ((state :lines) :min)
        indexes (line-index-from-point point grid-w)
        paths (map (fn [[linetype-max max-lines-for-type] [linetype-min min-lines-for-type]]
                     (assert (= linetype-max linetype-min) (str "Map is not mixing the same lines - " linetype-max " with " linetype-min))
                     (let [line-index (indexes linetype-max)
                           max-line (or (max-lines-for-type line-index) #{})
                           min-line (or (min-lines-for-type line-index) #{})
                           ]

                       (map
                         (fn [[nx ny :as new-point]]
                           (let [index-in-line (if (= linetype-max :v) ny nx)]
                             (cond
                               (not (in-bounds? grid-w grid-h new-point)) :wall
                               (contains? max-line index-in-line) :max
                               (contains? min-line index-in-line) :min
                               :else :empty)))
                         (map (partial map + point) (directors linetype-max)))))
                   max-lines min-lines)]
    (boolean (some true? (map (fn [path]
                                (let [parts (partition 5 1 (assoc (into [] path) 5 :max))]
                                  (reduce #(or %1
                                               (apply (partial = :max) %2))
                                          false
                                          parts)
                                  )) paths)))))

(defn- negamax-inner
  ""
  [state alpha beta got-time? is-first-player max-depth grid-width grid-height]

  (if (empty? (state true))
    {:best-move [(long (/ grid-width 2)) (long (/ grid-height 2))]}
    (if (and (is-terminal-state? state))
        {:best-move  (state :last-move)
         :best-value (state :heuristic-result)}

      (if (= max-depth 0)
        {:best-move  (state :last-move)
         :best-value (state :heuristic-result)
         :who-win?   nil}

        (loop
            [sucessors (generate-successor-states state grid-width grid-height (not is-first-player)) ; Flip is first player.
             best {:best-value Double/NEGATIVE_INFINITY
                   :best-move  []
                   :who-win?   nil}
             alpha alpha]

          (if (empty? sucessors)
            best
            (let [{child-best-move :best-move tmp-child-best-value :best-value who-win? :who-win?} (negamax-inner (first (first sucessors))
                                                                                                                  (- beta)
                                                                                                                  (- alpha)
                                                                                                                  got-time?
                                                                                                                  (not is-first-player)
                                                                                                                  (dec max-depth)
                                                                                                                  grid-width
                                                                                                                  grid-height)
                  child-best-value (- tmp-child-best-value)]

                  (if (> child-best-value (best :best-value))
                    (let [best {:best-value child-best-value :best-move child-best-move :who-win? who-win?}]
                      (if (> (best :best-value) alpha)
                        (let [alpha (best :best-value)]
                          (if (>= alpha beta)
                            best
                            (recur (rest sucessors) best alpha)))
                        (recur (rest sucessors) best alpha)))
                    (recur (rest sucessors) best alpha)))))))))

    (map
      #(map + point %)
      adjacent-transform)))
(def gen-surrounding-points (memoize gen-surrounding-points))

(defn gen-children-points
  [parent-state grid-w grid-h]
