             [clojure.edn :as edn]
             [clojure.core.async :refer [chan go <! >! <!! >!! alt! alts! put! close!]]
             [clojure.core.match :refer [match]]
-            [compojure.core :refer [routes]]
+            [compojure.core :refer [routes GET]]
             [compojure.route :as route])
   (:import [ji.domain.messages GameJoinMessage PlayerSetMessage]))
 
 (def app
   (routes
+    (GET "/" [] {:status 302 :headers {"Location" "/index.html"} :body ""})
     (route/files "/" {:root "out/public"})
     (route/files "/" {:root "public"})))
 

      (game/draw-cards num-add game)
      game)))

(defn fix-setless-board [game]
  (loop [game game]
    (if (empty? (game/solve-board (:board game)))
      (recur (game/draw-cards 3 game))

  (go
    (loop [game game
           clients []]
      (if-not (game-over? game)
        (let [[msg sc] (alts! (cons join-msgs (map :in clients)))]
          (if (= sc join-msgs)
            (let [{:keys [player-id client]} msg
                  clients' (conj clients client)]
              (recur (-> (game/add-player game player-id)
                         (step-game)
                         (broadcast-game! clients'))
                     clients'))
            (do
              (cond
                (nil? msg) ;; disconnect player
                (let [[client other-clients] (separate-client clients sc)]
                  (recur (-> game
                             (game/disconnect-player (:player-id client))
                             (step-game)
                             (broadcast-game! other-clients))
                         other-clients))

                (satisfies? IGameMessage msg) ;; TODO validate
                (recur (-> (apply-message msg game)
                           (step-game)
                           (broadcast-game! clients))
                       clients)
                :else
                (recur game clients)))))
        {:game game :clients clients}))))

(defn init-game-env!
