Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (defn has-winner? [board]
- (let [size (int (Math/sqrt (count board)))
- wins (generate-wins size)
- sum-wins (fn [board]
- (map #(sum-indexes board %) wins))]
- (> (count
- (filter #(or (= % size) (= % (* 9 size)))
- (sum-wins board)))
- 0)))
- (defn generate-rows [size]
- (let [gen-row (fn [idx] (take size (iterate inc idx)))]
- (map gen-row (take size (iterate #(+ size %) 0)))))
- (defn generate-cols [size]
- (let [gen-row (fn [idx] (take size (iterate #(+ size %) idx)))]
- (map gen-row (take size (iterate inc 0)))))
- (defn generate-throughs [size]
- (conj nil (take size (iterate #(+ 1 size %) 0))
- (take size (iterate #(+ -1 size %) (- size 1)))))
- (defn generate-wins [size]
- (concat (generate-rows size) (generate-cols size) (generate-throughs size)))
- (defn sum-indexes [board indexes]
- (apply + (map #(board %) indexes)))
- (defn valid-move? [pos board]
- (let [val (nth board pos 1)]
- (and (not= val 1)
- (not= val 9))))
- (defn print-board [board]
- (doseq [part (partition (int (Math/sqrt (count board))) board)] (println part)))
- (defmulti move (fn [player board] player))
- (defmethod move :com [player board]
- (println "Computer moves")
- (loop [mov (Math/round (* (rand) 8))]
- (if (valid-move? mov board)
- (assoc board mov 9)
- (recur (Math/round (* (rand) 8))))))
- (defmethod move :player [player board]
- (println "Player moves")
- (loop [mov (Integer. (read-line))]
- (if (valid-move? mov board)
- (assoc board mov 1)
- (do
- (println "Invalid move. Move again.")
- (recur (Integer. (read-line)))))))
- (defmulti player-name identity)
- (defmethod player-name :com [player]
- "Computer")
- (defmethod player-name :player [player]
- "Player")
- (defn next-player [player]
- (if (= player :player)
- :com
- :player))
- (defn play-turn [player board]
- (let [new-board (move player board)]
- (print-board new-board)
- (if (has-winner? new-board)
- (println (player-name player) "won!")
- (recur (next-player player) new-board))))
- (defn run [size]
- (let [empty-board (into [] (take (* size size) (repeat 0)))]
- (print-board empty-board)
- (play-turn :player empty-board)))
Advertisement
Add Comment
Please, Sign In to add comment