   ;; then determines if there has been a winner. If there has been a
   ;; winner, it marks the winner. Flips turn and returns true at this point
   (when-let [i (and
-                (< 0 move ncols)
+                (<= 0 move (dec ncols))
                 (->> (range (* move nrows) (* (inc move) nrows))
                      (filter (fn [i] (= (@state i) 0)))
                      first))]

            (when-not @winner
              (recur)))))
      ;; Cleanup
      (doseq [{:keys [latch ch-out]} players]
        (<! (notify ch-out))
        (>! ch-out {:type (if @winner "end" "disconnected")})
        (async/close! latch)))))

        dirs [1 nrows (inc nrows)]]
    (when (first
           (for [dir dirs]
             (<= (dec n-to-win)
                 (+
                  (count
                   (for [j (reductions + (repeat (- dir)))
                         :while (and (<= 0 j (dec ncols))
                                     (= cand (state-val j)))]
                     true))
                  (count
                   (for [j (reductions + (repeat (+ dir)))
                         :while (and (<= 0 j (dec ncols))
                                     (= cand (state-val j)))]
                     true))))))
      cand)))

