         rows-wrong (get wrong :rows-wrong)
         cols-wrong (get wrong :cols-wrong)
         problem-def (attr (sel1 :#puzzle-table) "problem-def")
-        server-id (get problem-def :id)]
-    (if (and (empty? rows-wrong)
-             (empty? cols-wrong))
+        server-id (get problem-def :id)
+        done (and (empty? rows-wrong)
+                  (empty? cols-wrong))]
+    (if done
       (rate-dialog server-id)
-      (js/alert (str "There are errors in rows:" rows-wrong "and columns:" cols-wrong)))))
+      (js/alert (str "There are errors in rows:" rows-wrong "and columns:" cols-wrong)))
+    done))
 
 (defn clear-puzzle []
-  (when-let [state @board]
-    (init-board! board (count (first state)) (count state)))
   (doseq [class ["num-clicked" "filled" "crossed"]
-          el (sel (str "." class))]
+          :let [el (sel (str "." class))]]
     (dommy/remove-class! el class)))
 
 (defn change-cell-style! [cell style]

;  [:tr [:td]        [:td#.num 2] [:td#.cell.c0.r2] [:td#.cell.c1.r2] [:td#.cell.c2.r2] [:td#.cell.c3.r2]]
;  [:tr [:td]        [:td#.num 4] [:td#.cell.c0.r3] [:td#.cell.c1.r3] [:td#.cell.c2.r3] [:td#.cell.c3.r3]]])

(def current-fill-style (atom nil)) ;one of [:empty :crossed :filled nil]

(def board (atom nil))

(def drag-type (atom :rect)) ; possible values :rect, :by-one

(defn range-inc [a b]
  (range (min a b) (inc (max a b))))



;;; Board functions

(defn init-board [width height]
  (->> (repeat width :empty)
       vec
       (repeat height)
       vec))

(defn change-cell-in-board [board x y new-state]
  (assoc-in board [y x] new-state))

(defn update-region-of-board [board [from-x from-y] [to-x to-y] new-state]
  (let [cells-to-change (for [x (range-inc from-x to-x)
                              y (range-inc from-y to-y)]
                          [y x])
        new-board (reduce #(assoc-in %1 %2 new-state) board cells-to-change)]
    new-board))

(defn pad [nums beg end value]
  (vec (concat (repeat beg value)
