update build
This commit is contained in:
parent
6223619d9e
commit
7f3891427e
15 changed files with 1099 additions and 900 deletions
33
cljs/replicant_tictactoe/core.cljs
Normal file
33
cljs/replicant_tictactoe/core.cljs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
;; COPIED FROM https://github.com/cjohansen/replicant-tic-tac-toe/blob/7a33fb12f0cd6658b2f555ff673dee031d4aa921/src/tic_tac_toe/core.cljs
|
||||
|
||||
(ns replicant-tictactoe.core
|
||||
(:require [replicant.dom :as r]
|
||||
[replicant-tictactoe.game :as game]
|
||||
[replicant-tictactoe.ui :as ui]))
|
||||
|
||||
(defn start-new-game [store]
|
||||
(reset! store (game/create-game {:size 3})))
|
||||
|
||||
(defn main []
|
||||
;; Set up the atom
|
||||
(let [store (atom nil)
|
||||
el (js/document.getElementById "app")]
|
||||
|
||||
;; Globally handle DOM events
|
||||
(r/set-dispatch!
|
||||
(fn [_ [action & args]]
|
||||
(case action
|
||||
:tic (apply swap! store game/tic args)
|
||||
:reset (start-new-game store))))
|
||||
|
||||
;; Render on every change
|
||||
(add-watch store ::render
|
||||
(fn [_ _ _ game]
|
||||
(->> (ui/game->ui-data game)
|
||||
ui/render-game
|
||||
(r/render el))))
|
||||
|
||||
;; Trigger the first render by initializing the game.
|
||||
(start-new-game store)))
|
||||
|
||||
(main)
|
||||
41
cljs/replicant_tictactoe/game.cljs
Normal file
41
cljs/replicant_tictactoe/game.cljs
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
;; COPIED FROM https://github.com/cjohansen/replicant-tic-tac-toe/blob/7a33fb12f0cd6658b2f555ff673dee031d4aa921/src/tic_tac_toe/game.cljs
|
||||
|
||||
(ns replicant-tictactoe.game)
|
||||
|
||||
(defn create-game [{:keys [size]}]
|
||||
{:next-player :x
|
||||
:size size})
|
||||
|
||||
(def next-player {:x :o, :o :x})
|
||||
|
||||
(defn winner? [tics path]
|
||||
(when (= 1 (count (set (map tics path))))
|
||||
path))
|
||||
|
||||
(defn get-winning-path [{:keys [size tics]} y x]
|
||||
(or (winner? tics (mapv #(vector y %) (range 0 size)))
|
||||
(winner? tics (mapv #(vector % x) (range 0 size)))
|
||||
(when (= y x)
|
||||
(winner? tics (mapv #(vector % %) (range 0 size))))))
|
||||
|
||||
(defn maybe-conclude [game y x]
|
||||
(if-let [path (get-winning-path game y x)]
|
||||
(-> (dissoc game :next-player)
|
||||
(assoc :over? true
|
||||
:victory {:player (get-in game [:tics [y x]])
|
||||
:path path}))
|
||||
(let [tie? (= (count (:tics game)) (* (:size game) (:size game)))]
|
||||
(cond-> game
|
||||
tie? (dissoc :next-player)
|
||||
tie? (assoc :over? true)))))
|
||||
|
||||
(defn tic [game y x]
|
||||
(let [player (:next-player game)]
|
||||
(if (or (get-in game [:tics [y x]])
|
||||
(<= (:size game) x)
|
||||
(<= (:size game) y))
|
||||
game
|
||||
(-> game
|
||||
(assoc-in [:tics [y x]] player)
|
||||
(assoc :next-player (next-player player))
|
||||
(maybe-conclude y x)))))
|
||||
50
cljs/replicant_tictactoe/style.css
Normal file
50
cljs/replicant_tictactoe/style.css
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* COPIED from https://github.com/cjohansen/replicant-tic-tac-toe/blob/7a33fb12f0cd6658b2f555ff673dee031d4aa921/resources/public/styles.css */
|
||||
.cell {
|
||||
aspect-ratio: 1 / 1;
|
||||
background: rgba(255, 255, 255, 0.8);
|
||||
border-radius: 6%;
|
||||
border: none;
|
||||
display: block;
|
||||
flex: 1 1 0%;
|
||||
outline: none;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cell-content {
|
||||
opacity: 1;
|
||||
transition: opacity 0.25s;
|
||||
}
|
||||
|
||||
.transparent {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.cell-dim {
|
||||
background: rgba(249, 249, 240, 0.3);
|
||||
}
|
||||
|
||||
.cell-highlight {
|
||||
background: #fcfcf3;
|
||||
}
|
||||
|
||||
.clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.board {
|
||||
--gap: 0.75rem;
|
||||
background: #833ab4;
|
||||
background: linear-gradient(90deg, #833ab4 0%, #fd1d1d 50%, #fcb045 100%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--gap);
|
||||
padding: var(--gap);
|
||||
max-width: 80vh;
|
||||
}
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: var(--gap);
|
||||
}
|
||||
75
cljs/replicant_tictactoe/ui.cljs
Normal file
75
cljs/replicant_tictactoe/ui.cljs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
;; COPIED FROM https://github.com/cjohansen/replicant-tic-tac-toe/blob/7a33fb12f0cd6658b2f555ff673dee031d4aa921/src/tic_tac_toe/ui.cljs
|
||||
|
||||
(ns replicant-tictactoe.ui)
|
||||
|
||||
(def mark-x
|
||||
[:svg {:xmlns "http://www.w3.org/2000/svg"
|
||||
:viewBox "0 -10 108 100"}
|
||||
[:path
|
||||
{:fill "currentColor"
|
||||
:d "m1.753 69.19.36-1.08q.35-1.09 1.92-2.97 1.58-1.87 3.85-3.84 2.29-1.97 4.6-3.54 2.31-1.57 4.93-3.24 2.62-1.66 4.65-2.9 2.04-1.23 3.91-2.27 1.87-1.05 3.98-2.31 2.11-1.27 4.12-2.5 2.01-1.24 4.33-2.51l4.6-2.52q2.27-1.25 4.84-2.86 2.56-1.62 5.03-3.09 2.47-1.47 4.5-2.88 2.03-1.4 3.82-2.82t3.81-3.47q2.01-2.06 3.7-3.51 1.69-1.46 3.47-3.03 1.77-1.57 4.01-3.69 2.24-2.11 4.13-3.7 1.89-1.58 3.93-2.97 2.04-1.39 4.05-2.49 2.01-1.11 5.26-2.54 3.24-1.44 4.48-1.46 1.24-.01 2.42.37 1.18.37 2.18 1.11 1 .74 1.71 1.75.71 1.02 1.06 2.21.34 1.19.3 2.43-.05 1.24-.5 2.39-.44 1.16-1.23 2.12-.79.95-1.84 1.61-1.05.65-2.26.94-1.21.28-2.44.16-1.23-.11-2.37-.62-1.13-.5-2.04-1.34-.91-.84-1.51-1.93-.6-1.08-.81-2.3-.22-1.22-.04-2.45.18-1.23.75-2.33.56-1.1 1.45-1.97.89-.86 2.01-1.4 1.11-.54 2.35-.69 1.23-.15 2.44.1t2.29.87q1.07.63 1.88 1.56.82.93 1.29 2.08.48 1.14.56 2.38.09 1.24-.23 2.44-.31 1.19-.99 2.23-.68 1.04-1.66 1.8-.98.76-2.15 1.18l-1.16.41-2.28 1.17q-2.28 1.18-4.38 2.7-2.1 1.51-4.2 3.44-2.1 1.92-4.18 3.7-2.08 1.77-3.9 3.44-1.81 1.68-3.41 3.13-1.6 1.46-3.38 3.09-1.79 1.62-3.44 2.97-1.66 1.34-3.53 2.4-1.88 1.06-4.17 2.65-2.3 1.6-4.79 2.74-2.48 1.14-4.98 2.71-2.5 1.57-4.51 2.47-2.01.9-3.99 1.87-1.98.97-3.88 2.02-1.91 1.05-4.38 2.34-2.46 1.28-4.94 2.53-2.47 1.25-4.48 2.38-2 1.12-3.96 2.14-1.95 1.01-3.83 1.99-1.89.98-4.37 2.05-2.48 1.06-2.96 2.01-.48.96-.78 1.49-.3.53-.71.97-.41.44-.92.77-.51.34-1.09.54-.57.2-1.17.25-.6.06-1.2-.03t-1.16-.32q-.56-.23-1.05-.59-.49-.35-.89-.82-.39-.46-.65-1.01-.27-.54-.4-1.14-.13-.59-.12-1.19.02-.6.18-1.19l.16-.59Z"}]
|
||||
[:path
|
||||
{:fill "currentColor"
|
||||
:d "m28.099 4.991 2.69 1.97q2.69 1.96 4.5 3.22 1.8 1.28 4.54 3.46 2.74 2.18 4.57 3.89t3.38 3.72q1.54 2.02 2.88 4.3 1.34 2.28 2.83 4.46 1.48 2.18 2.63 4.14 1.15 1.96 2.74 4.07 1.59 2.1 3.59 4.19 1.99 2.08 4.23 4.48 2.24 2.4 3.7 4.04 1.47 1.64 2.91 3.23 1.44 1.59 3.08 3.58 1.64 1.99 3.51 4.08 1.87 2.09 3.55 3.77 1.69 1.68 4.1 3.51 2.42 1.83 3.9 2.58 1.48.74 2.14 1.34.66.6 1.15 1.33.5.74.8 1.57.31.84.4 1.72.1.88-.02 1.76-.12.88-.44 1.71-.33.82-.84 1.55-.51.72-1.19 1.3-.67.58-1.46.98-.79.41-1.65.61-.87.2-1.76.19-.88-.01-1.74-.24-.86-.22-1.64-.64-.78-.42-2.27-2.72-1.48-2.3-1.52-3.49-.03-1.19.31-2.33.35-1.14 1.04-2.11.69-.97 1.66-1.67.96-.7 2.1-1.05 1.14-.35 2.33-.32 1.19.02 2.31.43t2.05 1.15q.93.75 1.58 1.75.64 1 .93 2.15.29 1.16.2 2.35-.09 1.18-.56 2.28-.47 1.1-1.26 1.99-.79.88-1.83 1.47t-2.2.82q-1.17.23-2.35.07-1.19-.16-2.25-.68-1.07-.53-1.92-1.37-.84-.84-1.37-1.9-.54-1.07-.7-2.25-.17-1.18.06-2.35.22-1.17.8-2.21.58-1.04 1.47-1.84.88-.79 1.98-1.27 1.09-.47 2.28-.57 1.18-.1 2.34.18 1.16.29 2.16.93 1.01.63 1.76 1.56.74.93-.33-.26-1.07-1.18-.41-.58.66.59 1.15 1.33.5.74.8 1.57.31.83.4 1.72.1.88-.02 1.76-.12.88-.44 1.7-.33.83-.84 1.55-.51.73-1.19 1.31-.67.58-1.46.98-.79.41-1.65.61-.87.2-1.75.19-.89-.01-1.75-.24-.86-.22-1.64-.64-.78-.42-2.73-1.57-1.95-1.14-4.26-2.95-2.31-1.8-3.87-3.43-1.57-1.62-3.17-3.29-1.6-1.66-3.55-4.05-1.95-2.39-3.33-4.15-1.39-1.76-2.77-3.4-1.38-1.64-3.07-3.56-1.7-1.91-3.91-4.13-2.2-2.22-3.74-4.1-1.54-1.88-2.79-3.75-1.24-1.87-2.4-4.33t-2.39-4.46q-1.23-2.01-2.4-4.59-1.17-2.59-2.53-5.01-1.36-2.43-3.35-4.44-1.99-2.02-4.52-4.27-2.54-2.25-5.33-4.04-2.81-1.79-3.28-2.21-.47-.41-.83-.92-.35-.51-.58-1.1-.22-.58-.3-1.2-.08-.62-.01-1.23.08-.62.29-1.21.22-.58.58-1.1.35-.51.81-.93.47-.42 1.02-.71t1.16-.45q.61-.15 1.23-.15t1.22.14q.61.15 1.17.44l.55.28Z"}]])
|
||||
|
||||
(def mark-o
|
||||
[:svg {:xmlns "http://www.w3.org/2000/svg"
|
||||
:viewBox "0 0 114 114"}
|
||||
[:path
|
||||
{:fill "none"
|
||||
:stroke "currentColor"
|
||||
:stroke-linecap "round"
|
||||
:stroke-width "6"
|
||||
:d "M74.616 8.935c7.73 2.38 15.96 9.34 21.58 16.04 5.63 6.69 10.57 15.46 12.18 24.11 1.6 8.65.74 19.67-2.53 27.77-3.27 8.11-10.12 15.37-17.09 20.88-6.98 5.51-16.07 10.81-24.76 12.17-8.7 1.35-19.32-.76-27.42-4.06-8.1-3.29-15.73-8.93-21.21-15.73-5.48-6.81-10.32-16.5-11.67-25.09-1.35-8.6.19-18.39 3.57-26.51 3.38-8.11 9.99-16.6 16.71-22.19 6.72-5.59 13.95-10.52 23.63-11.36 9.68-.84 28.04 4.34 34.45 6.32 6.42 1.97 4.37 4.6 4.04 5.55m-48.33-9.69c7.65-3.32 19.78-3.63 28.63-2.01 8.86 1.63 17.85 5.89 24.49 11.76 6.64 5.87 12.7 15.08 15.37 23.48 2.67 8.41 2.5 18.4.65 26.95-1.85 8.54-5.98 17.59-11.77 24.34-5.78 6.74-14.56 13.05-22.93 16.11-8.37 3.06-18.75 4.19-27.29 2.25-8.54-1.93-17.37-7.89-23.96-13.87-6.59-5.97-12.89-13.58-15.57-21.96-2.69-8.39-2.31-19.94-.56-28.34 1.75-8.4 5.21-15.74 11.06-22.09 5.85-6.35 19.92-13.32 24.04-16.01 4.12-2.7.37-1.1.67-.16"}]])
|
||||
|
||||
(defn render-cell [{:keys [content on-click dim? highlight? clickable?]}]
|
||||
[:button.cell
|
||||
{:on {:click on-click}
|
||||
:class (cond-> []
|
||||
dim? (conj "cell-dim")
|
||||
highlight? (conj "cell-highlight")
|
||||
clickable? (conj "clickable"))}
|
||||
(when content
|
||||
[:div.cell-content
|
||||
{:replicant/mounting {:class "transparent"}
|
||||
:replicant/unmounting {:class "transparent"}}
|
||||
content])])
|
||||
|
||||
(defn render-board [{:keys [rows]}]
|
||||
[:div.board
|
||||
(for [row rows]
|
||||
[:div.row
|
||||
(for [cell row]
|
||||
(render-cell cell))])])
|
||||
|
||||
(defn render-game [{:keys [board button]}]
|
||||
[:div
|
||||
(render-board board)
|
||||
(when button
|
||||
[:button {:on {:click (:on-click button)}
|
||||
:style {:margin-top 20
|
||||
:font-size 20}}
|
||||
(:text button)])])
|
||||
|
||||
(def player->mark
|
||||
{:x mark-x
|
||||
:o mark-o})
|
||||
|
||||
(defn game->ui-data [{:keys [size tics victory over?]}]
|
||||
(let [highlight? (set (:path victory))]
|
||||
{:button (when over?
|
||||
{:text "Start over"
|
||||
:on-click [:reset]})
|
||||
:board
|
||||
{:rows
|
||||
(for [y (range size)]
|
||||
(for [x (range size)]
|
||||
(if-let [player (get tics [y x])]
|
||||
(let [victorious? (highlight? [y x])]
|
||||
(cond-> {:content (player->mark player)}
|
||||
victorious? (assoc :highlight? true)
|
||||
(and over? (not victorious?)) (assoc :dim? true)))
|
||||
(if over?
|
||||
{:dim? true}
|
||||
{:clickable? true
|
||||
:on-click [:tic y x]}))))}}))
|
||||
Loading…
Add table
Add a link
Reference in a new issue