Skip to content

Instantly share code, notes, and snippets.

@visibletrap
Created September 19, 2017 16:21
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 visibletrap/7d4c6887411fd39c25ac5b5b858b0761 to your computer and use it in GitHub Desktop.
Save visibletrap/7d4c6887411fd39c25ac5b5b858b0761 to your computer and use it in GitHub Desktop.
ui/run-game
(ns clojure-playground.tap.model)
(def empty-board
[[:_ :_ :_]
[:_ :_ :_]
[:_ :_ :_]])
(def win-patterns
[[[0 0] [1 0] [2 0]]
[[0 1] [1 1] [2 1]]
[[0 2] [1 2] [2 2]]
[[0 0] [0 1] [0 2]]
[[1 0] [1 1] [1 2]]
[[2 0] [2 1] [2 2]]
[[0 0] [1 1] [2 2]]
[[2 0] [1 1] [0 2]]])
(defn start-game []
{:board empty-board
:player :X
:status :started
:winner nil})
(def next-player {:X :O :O :X})
(defn mark-on-board [board player [x y]]
(assoc-in board [y x] player))
(defn at [board [x y]]
(get-in board [y x]))
(defn playable? [board pos]
(= (at board pos) :_))
(defn win-pattern? [board pattern]
(let [marks (map #(at board %) pattern)]
(or
(apply = :O marks)
(apply = :X marks))))
(defn win? [board]
(some #(win-pattern? board %) win-patterns))
(defn full? [board]
(->> [[0 0] [0 1] [0 2] [1 0] [1 1] [1 2] [2 0] [2 1] [2 2]]
(some #(= :_ (at board %)))
(not)))
(defn win [{:keys [board player] :as game}]
(-> game
(assoc :status :win)
(assoc :winner player)))
(defn draw [game]
(-> game
(assoc :status :draw)
(assoc :winner :none)))
(defn continue [game]
(-> game
(assoc :status :ok)
(update :player next-player)))
(defn place [{:keys [player] :as game} pos]
(let [{:keys [board] :as next-game}
(update game :board mark-on-board player pos)]
(cond
(win? board) (win next-game)
(full? board) (draw next-game)
:else (continue next-game))))
(defn play [game pos]
(let [{:keys [board]} game]
(cond
(playable? board pos)
(place game pos)
:else
(assoc game :status :invalid-pos))))
(defn test-play-all [pos-list]
(reduce (fn [g p] (play g p)) (start-game) pos-list))
(comment
; Until win
(test-play-all [[0 0] [2 2] [1 0] [1 2] [2 0]])
; Out of board
(test-play-all [[3 3]])
; Play same pos
(test-play-all [[0 0] [0 0]])
; Draw
(test-play-all [[0 0] [1 1] [0 2] [0 1] [2 1] [1 0] [1 2] [2 2] [2 0]])
)
(ns clojure-playground.tap.ui
(:require [clojure-playground.tap.model :as model]))
(defn input->pos
[s]
(into [] (map #(Character/getNumericValue ^char %) (seq s))))
(defn play-turn [{:keys [player] :as game} _]
(println "Turn:" (name player))
(print "=> ")
(flush)
(let [input (read-line)]
(if (= "e" input)
(println "Bye!")
(let [pos (input->pos input)
{:keys [board status winner] :as new-game} (model/play game pos)]
(println (name player) "plays" pos)
(println board)
(case status
:win (do (println "Winner is" (name winner))
(reduced new-game))
:draw (do (println "Draw game")
(reduced new-game))
:invalid-pos (do (println "Wrong position! Try again")
new-game)
:ok new-game)))))
(defn run-game
[]
(println "Input format 'XY'")
(reduce play-turn (model/start-game) (range)))
(comment
(run-game))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment