           position location)
          ))
 
-(defn test-pawn-moves[]
-  (let [ position starting-position]
-    (pprint (map (partial move->algebraic-notation starting-position)
-                 (pawn-moves starting-position [0 1])))
-    ))
-
-
-(def piece-color {"r" :black "n" :black "b" :black "q" :black "k" :black
-                  "R" :white "N" :white "B" :white "Q" :white "K" :white
-                  "P" :white})
-
-;; (count (moves (string->position "  n\n   \n   " :black) :black))
-;; (:piece-locations (string->position "  n\n   \n   " :black))
-(defn moves[position white-or-black]
-  (when true ;;debug
+
+
+
+;; (count (moves (string->position "  n\n   \n   " :black) ))
+;; (:piece-locations (string->position "  n\n   \n   " ))
+
+(def opposite-color {:black :white :white :black})
+(defn flip-position[position]
+   (update-in position [:player-to-move] opposite-color)
+  )
+
+(defn locations-under-attack-moves[position]
+  {
+   ;;:post  [(set? %)]
+   :pre [(my-is-a? :position position)] }
+  (mapcat 
+    (fn[[loc piece :as z]]
+      (let [
+            piece-info (get pieces-info 
+                            (keyword (clojure.string/lower-case piece)))]
+        (cond (:ranging piece-info)
+              (ranging-moves position loc (:rules piece-info)) 
+              (is-pawn? piece)
+              (pawn-capturing-locations position loc) 
+              (is-knight? piece)
+              (non-ranging-moves position loc (:rules piece-info)) 
+              (is-king? piece)
+              (non-ranging-moves position loc (:rules piece-info))
+              true
+              (assert false)
+              ))) 
+    (filter (fn[[_ piece]]
+              (=   (piece-color piece)
+                 (:player-to-move position))) 
+            (:piece-locations position))
+    ))
+
+;; (locations-under-attack starting-position)
+   ;;      (locations-under-attack (string->position "Bk" :black))
+;;
+(defn locations-under-attack[position]
+  {
+   :post  [(set? %)]
+   :pre [(my-is-a? :position position)] }
+
+  (let [enemy-position (flip-position position)]
+    (set (filter (partial unoccupied? enemy-position)
+            (map second (locations-under-attack-moves enemy-position))))
+  ))
+
+
+
+;; (println starting-position)
+
+;; (king-location starting-position)
+(defn king-location[position]
+  "TODO: don't use scan???"
+  (let [piece (if (= :white (:player-to-move position)) 
+                "K"
+                "k")]
+    (some #(if (= piece (second %))
+                (first %))
+          (:piece-locations position))
+    ))
+;; (update-position starting-position)
+(defn update-position[position]
+  (let [under-attack 
+           (locations-under-attack position)
+        ]
+   (assoc position 
+          :locations-under-attack
+           under-attack
+          :in-check
+          (contains? under-attack (king-location position))
+
+  )))
+
+;; (string->position "r" :white)
+(defn string->position[string color]
+  {:post  [(is-position? %)]
+   :pre [(string? string)
+         (is-color? color)] }
+  (let [lines (vec (reverse (clojure.string/split-lines string)))
+        ]
+    (update-position
+    { :type :position
+     :player-to-move color
+     :piece-locations
+     (into (sorted-map) 
+           (remove 
+             (fn [x]
+               (or (nil? (second x))
+                   (= "" (second x))
+                   (= " " (second x ))))
+             (for [x (range 8) y (range 8)
+                   :let [ location [x y]
+                         piece (str (get (get lines y) x)) 
+                         ]
+                   ]
+               [location piece]  ;; map entry
+               )))
+     })))
+
+(def starting-position
+  "Horizontal rows are ranks. Vertical rows are files"
+  (string->position starting-position-string :white))
+
+(defn moves[position]
+  (when debug
     (println "entering moves")
     (println "position is" position)
     )

            rules 
            )))


(defn pawn-captures[position [x y :as location]]
  "return valid capture moves for the pawn at the location on the position"


(defn test-knight-moves[]
  (is (= 8 
         (count (moves (string->position "  n\n   \n   " :black)))

         )))
(test-knight-moves)
(defn test-moves[]
  (println "test-moves")
  (moves (string->position "R" :white) )
  )
;; (test-moves)
(defn test-position->string[]
  (is (= 
        starting-position-string
        (position->string
          (string->position starting-position-string :white)))))
(defn test-pawn-moves[]
  (let [ position starting-position]
    (pprint (map (partial move->algebraic-notation starting-position)
                 (pawn-moves starting-position [0 1])))
    ))
(defn test-starting-moves[]
  (let [position starting-position]
    (map #(move->algebraic-notation position %) 
         (moves starting-position))))
(defn run-tests[]
  (test-king-moves)
  (test-king-cannot-move-to-a-location-under-attack)
  (test-pawn-moves)
  (test-position->string)
  (test-starting-moves)
