-
-
Save kindlychung/bd9e46eda02784cec68d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns cina.tic-tac-toe) | |
(defn triple-winner? | |
[triple] | |
(cond | |
(every? #{:x} triple) :x | |
(every? #{:o} triple) :o | |
:else nil)) | |
(declare triples) | |
(defn winner? | |
[board] | |
(first (filter #{:x :o} | |
(map triple-winner? (triples board))))) | |
(defn triples | |
[board] | |
(concat | |
(partition-all 3 board) | |
(list | |
(take-nth 3 board) | |
(take-nth 3 (drop 1 board)) | |
(take-nth 3 (drop 2 board)) | |
(take-nth 4 board) | |
(take-nth 2 (drop-last 2 (drop 2 board)))))) | |
(defn full-board? | |
[board] | |
(every? #{:x :o} board)) | |
(declare player-name) | |
(defn print-board | |
[board] | |
(let [board (map #(if (keyword? %) (player-name %) %) board) | |
print-piece (fn [x] | |
(let [p (nth board x) | |
p-to-print (if (= 2 (mod x 3)) | |
(str p \newline) | |
(str p \space))] | |
(print p-to-print)))] | |
(map print-piece (range (count board))))) | |
(defn player-name | |
[player] | |
(subs (str player) 1)) | |
(def starting-board | |
[1 2 3 4 5 6 7 8 9]) | |
(def player-sequence (cycle [:x :o])) | |
(defn get-move | |
[board] | |
(let [input (try (. Integer parseInt (read-line)) | |
(catch Exception e nil))] | |
(if (some #{input} board) | |
input | |
nil))) | |
(defn take-turn | |
[player board] | |
(loop [move (do | |
(println "Choose your move, " (str player)) | |
(get-move board))] | |
(if move | |
(assoc board (dec move) player) | |
(do | |
(println "Move was invalid. Choose again, " (str player)) | |
(recur (get-move board)))))) | |
(defn play-game | |
[] | |
(loop [board starting-board | |
player-sequence player-sequence] | |
(let [winner (winner? board)] | |
(println "Current board:") | |
(print-board board) | |
(cond | |
winner (println "Player" (player-name winner) "wins!") | |
(full-board? board) (println "Game is a draw") | |
:else (recur (take-turn (first player-sequence) board) | |
(rest player-sequence)))))) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment