tick-tack-toe(clojure)


(def won-pattern [2r111000000 2r000111000 2r000000111 2r100100100 2r010010010 2r001001001 2r100010001 2r001010100])

(defn win? [prots]
  (if (> 2 (count prots)) false
    (let [current-bit (apply bit-or (map #(.intValue (Math/pow 2 (- % 1))) prots))]
      (some (fn [x] (= x (bit-and current-bit x))) won-pattern))))

(defn judge [a-prots b-prots f?]
  (let [target (if f? a-prots b-prots)
        enemy (if f? b-prots a-prots)
        t-name (if f? "○" "×")
        e-name (if f? "×" "○")]
    (cond
     (win? target) (str t-name " won.")
     (not= target (distinct target)) (str "Foul : " e-name " won.")
     (some #(.contains target %) enemy) (str "Foul : " e-name " won.")
     :else nil)))

(defn solve [all-prots]
  (loop [a-prots [] b-prots [] r-prots all-prots f? true]
    (letfn [(add [coll f?] (if f? (conj coll (read-string (str (first r-prots)))) coll))]
      (let [a-prots (add a-prots f?)
            b-prots (add b-prots (not f?))
            result (judge a-prots b-prots f?)]
        (if result result
          (if (= (count (concat a-prots b-prots)) 9) "Draw game." (recur a-prots b-prots (rest r-prots) (not f?))))))))

(solve "79538245")
(solve "35497162193")
(solve "61978543")
(solve "254961323121")
(solve "6134278187")
(solve "9625663381")
(solve "4319581")
(solve "2368799597")
(solve "18652368566")
(solve "965715")
(solve "38745796")
(solve "371929")
(solve "758698769")
(solve "42683953")
(solve "618843927")
(solve "36535224")
(solve "882973")
(solve "653675681")
(solve "9729934662")
(solve "972651483927")
(solve "5439126787")
(solve "142583697")
(solve "42198637563")
(solve "657391482")