Skip to content

Instantly share code, notes, and snippets.

@apropos-cast
Last active October 14, 2020 15:01
Show Gist options
  • Save apropos-cast/5b2994f60b45f59d3b1a85470fd38d20 to your computer and use it in GitHub Desktop.
Save apropos-cast/5b2994f60b45f59d3b1a85470fd38d20 to your computer and use it in GitHub Desktop.
September 30, 2020
(ns test.game-tree
(:require [clojure.pprint :refer [pprint]]))
(def start-game [[nil nil nil]
[nil nil nil]
[nil nil nil]])
(def unwon-game [[nil nil nil]
[:x nil nil]
[nil nil nil]])
(def test-game [[nil :x nil]
[nil :x nil]
[nil :x nil]])
(def draw-game [[:o :x :o]
[:x :x :o]
[:x :o :x]])
(defn whose-turn? [game]
(let [moves (apply concat game)
xs (filter #{:x} moves)
os (filter #{:o} moves)]
(if (> (count os) (count xs))
:o
:x)))
(defn possible-moves [game]
(for [x (range 3)
y (range 3)
:when (nil? (get-in game [y x]))]
[x y]))
(defn make-move [game player [x y]]
(assoc-in game [y x] player))
(def lines
(concat
(for [y (range 3)]
(for [x (range 3)]
[x y]))
(for [x (range 3)]
(for [y (range 3)]
[x y]))
[(for [y (range 3)]
[y y])
(for [y (range 3)]
[y (- 2 y)])]))
(def not-empty? seq)
(defn winner [game]
(let [full-lines (filter (fn [line]
(every? boolean line))
(map (fn [line]
(map (fn [coord]
(get-in game coord)) line))
lines))
winner-lines (filter #(apply = %) full-lines)]
(cond
(not-empty? winner-lines)
(ffirst winner-lines)
(= 8 (count full-lines))
:draw
:else
nil)))
(defn run [game]
(let [w (winner game)]
(if w
[{:game game
:winner w}]
(let [current (whose-turn? game)
next ({:x :o :o :x} current)]
(->> game
(possible-moves)
(map #(make-move game next %))
(mapcat run))))))
(defn pp [game]
(run! println game))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment