crepl Tic Tac Toe example with atom sync
(ns crepl.tic-tac-toe | |
(:require [reagent.core :as r] | |
crepl.atom-sync)) | |
;; use this instead of reagent.core/atom to keep the state in sync | |
(def data (crepl.atom-sync/atom-sync {:turn :X})) | |
(def win-lines (-> #{} | |
(into (for [i (range 3)] | |
(for [j (range 3)] | |
[i j]))) | |
(into (for [j (range 3)] | |
(for [i (range 3)] | |
[i j]))) | |
(conj (for [d (range 3)] | |
[d d])) | |
(conj (for [d (range 3)] | |
[d (- 2 d)])))) | |
(defn find-winner [board] | |
(some (fn [cells] | |
(when-let [[winner] (#{[:X :X :X] [:O :O :O]} (map #(get-in board %) cells))] | |
[winner (set cells)])) | |
win-lines)) | |
(defn cell [i j piece winner-cell game-over] | |
(let [play (fn [] | |
(when-not (or piece game-over) | |
(swap! data (fn [{:keys [turn board] :as d}] | |
(-> d | |
(assoc-in [:board i j] turn) | |
(update :turn {:X :O, :O :X}))))) | |
)] | |
[:a {:href "#", :on-click (fn [e] (play) (.preventDefault e))} | |
[:div {:style {"display" "inline-block" | |
"width" "40px" | |
"height" "40px" | |
"lineHeight" "40px" | |
"fontSize" "30px" | |
"paddingLeft" "8px" | |
"paddingBottom" "0px" | |
"color" (if piece "black" "white") | |
"backgroundColor" (if winner-cell "green" "white") | |
"borderLeft" (if (#{1 2} j) | |
"2px solid black" | |
"0px") | |
"borderTop" (if (#{1 2} i) | |
"2px solid black" | |
"0px")}} | |
(if piece (name piece) "#")]])) | |
(defn tic-tac-toe [] | |
(let [{:keys [turn board]} @data | |
[winner winner-line] (find-winner board) | |
tie (when-not winner | |
(= (count (mapcat val board)) 9)) | |
reset-board (fn [] | |
(reset! data {:turn turn}))] | |
[:div | |
[:h3 "TicTacToe"] | |
(cond | |
winner | |
[:div (name winner) " has won! " | |
[:button {:on-click reset-board} | |
"Play again"]] | |
tie | |
[:div "Tie! " | |
[:button {:on-click reset-board} | |
"Play again"]] | |
:else | |
[:div "To play:" turn]) | |
(for [i (range 3) | |
j (range 3)] | |
[:span {:key (+ (* j 3) i)} | |
[cell i j (get-in board [i j]) (contains? winner-line [i j]) (or winner tie)] | |
(when (= j 2) [:br]) | |
]) | |
])) | |
(r/render-component [tic-tac-toe] | |
(.getElementById js/document "app")) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment