Skip to content

Instantly share code, notes, and snippets.

@bhauman
Last active December 22, 2015 15:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bhauman/6490813 to your computer and use it in GitHub Desktop.
Save bhauman/6490813 to your computer and use it in GitHub Desktop.
This is a tic tac toe implementation by Jeff Dik
(ns tic-tac-toe)
(defn empty-board [size]
(let [row (vec (repeat size nil))]
(vec (repeat size row))))
(defn prn-board [board]
(dorun (map prn board)))
(defn place [board row col marker]
(assoc-in board [row col] marker))
(defn empty-spot? [board row col]
(nil? (get-in board [row col])))
(defn game-over? [board]
(every? identity (apply concat board)))
(defn valid-move? [board row col]
(and (every? #(< % (count board)) [row col])
(empty-spot? board row col)))
(defn board-seq [board]
(let [r (range (count board))
rows board
cols (apply map vector board)
diag1 (map #(get-in board [%1 %2]) r r)
diag2 (map #(get-in board [%1 %2]) r (reverse r))]
(concat rows cols [diag1 diag2])))
(defn winner? [board]
(some #(if (and (apply = %)
(first %))
(first %))
(board-seq board)))
(defn new-game [size players]
{:board (empty-board size)
:players (cycle players)})
(defn turn [{:keys [board players] :as game} row col]
(if (valid-move? board row col)
{:board (place board row col (first players))
:players (next players)}
game))
(defn verdict [old-board board]
(if (= old-board board)
"Invalid move. Try again!"
(if-let [winner (winner? board)]
(str winner " wins!")
(if (game-over? board)
"Tie."¯
"Next turn..."))))
(defn take-turn [game row col]
(let [old-board (:board @game)
{:keys [board]} (swap! game turn row col)]
(prn-board board)
(println (verdict old-board board))))
(comment
(def game (atom (new-game 3 [:x :o])))
(take-turn game 1 1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment