 
                   :score 0}))
 
+; required for pausing/resuming the gravity routine
+(def pause-grav (chan))
+(def resume-grav (chan))
+
 ;;------------------------------------------------------------
 ;; STATE MONITOR
 ;;------------------------------------------------------------

        board (:board @state)]
    (swap! state assoc  :board (write-piece-to-board piece x y board)
                        :piece nil)

    ; If collapse routine returns a channel...
    ; then wait for it before spawning a new piece.

      (go (<! collapse-anim) (try-spawn-piece!))
      (try-spawn-piece!))))

(defn try-gravity!
  "Move current piece down 1 if possible, else lock the piece."
  []
  (let [piece (:piece @state)
        [x y] (:position @state)
        board (:board @state)
        ny (inc y)]
    (if (piece-fits? piece x ny board)
      (swap! state assoc-in [:position 1] ny)
      (lock-piece!))))

(defn go-go-gravity!
  "Starts the gravity routine."
  []
  ; Make sure gravity starts in paused mode.
  ; Spawning the piece will signal the first "resume".
  (put! pause-grav 0)

  (go
    (loop []
      (let [cs [(timeout 1000) pause-grav]  ; channels to listen to (timeout, pause)
            [_ c] (alts! cs)]               ; get the first channel to receive a value
        (if (= pause-grav c)                ; if "pause" received, wait for "resume"
          (<! resume-grav)
          (try-gravity!))
        (recur)))))

;;------------------------------------------------------------
;; Input-driven STATE CHANGES
