           new-list)))
     ))
 
-
-;; -----------------------------------------
-;; GAME LOOP
-;; -----------------------------------------
-
-(defn- handle-ai! []
-  (let [ai-algo (get @ai-players @current-player)
-        move (ai-algo @game @current-player)]
-    (update-game! play-move move)))
+(defn- handle-game-event!
+  [msg]
+  (case msg
+    :new-game (swap! app-state assoc-in [:games] (list (new-game)))
+    :restart (swap! app-state update-in [:games] #(take-last 1 %))
+    :undo (cancel-last-move!)
+    ))
 
 (defn start-game-loop
   "Manage transitions between player moves, ai moves, and generic game events"

(defn show-top-panel
  [scores player]
  [:div.scores
   [top-panel-button new-game! (special-char "&#9733;")]
   [top-panel-button #(swap! app-state update :help not) "?"]
   (show-scores scores player)
   [top-panel-button restart-game! (special-char "&#x21bb;")]
   [top-panel-button cancel-last-move! (special-char "&#x21A9;")]])

(defn max-board-height []
  (- (-> (dom/getWindow) dom/getViewportSize .-height) 100))

(def ai-players (reaction (get-in @game [:ai-players])))
(def end-of-game (reaction (nil? @current-player)))

(defn is-ai? [player]
  (contains? @ai-players player))


;; -----------------------------------------
;; GAME LOOP
;; -----------------------------------------

(defn update-game! [f & args]
  (swap! app-state update-in [:games] conj (apply f @game args)))

(defn- handle-ai! []
  (let [ai-algo (get @ai-players @current-player)
        move (ai-algo @game @current-player)]
    (update-game! play-move move)))

(defn cancel-last-move! []
  (swap! app-state update-in [:games]
