Skip to content

Instantly share code, notes, and snippets.

(ns tictactoe.view.frame
(:require
[tictactoe.view.board :as board]
[tictactoe.view.panel :as panel]))
(defn render
"Rendering the main frame of the game,
takes as input the callbacks to trigger events"
[{:keys [board] :as turn} callbacks]
(defn- make-button
[on-click txt]
[:button.top-button {:on-click on-click} txt])
(defn render-top-panel
"Render the top panel:
* The restart game button
* The title of the game
* The undo button"
[turn {:keys [on-restart on-undo]}]
(defn- special-char
[str-code]
[:div {:dangerouslySetInnerHTML {:__html str-code}}])
(def back-arrow (special-char "←"))
(def circle-arrow (special-char "↻"))
(defn render-board
"Render the board:
* Creates a SVG panel
* Render the cells in it"
[board {:keys [on-move]}]
(utils/square-svg-panel
{:model-size board/size
:pixel-size cst/board-pixel-size}
(for [cell board]
[cell/render-cell cell on-move]
(defn new-game []
[turn/start-turn])
(defn current-turn
[game]
(peek game))
(defn play-move
"Play current player move at the provided coordinate"
[game coord]
{:board {[0 1] :owner/none,
[1 2] :owner/none,
[0 0] :owner/cross,
[2 2] :owner/none,
[0 2] :owner/circle,
[1 1] :owner/none,
[2 1] :owner/none,
[1 0] :owner/cross,
[2 0] :owner/none},
:player :owner/circle}
{:board {:owner/cross #{[0 0] [1 0]} ;; Cells owned by "cross"
:owner/circle #{[0 2]}} ;; Cells owned by "circle"
:player :owner/circle} ;; Next player to play
[{:board {[0 1] :owner/none,
[1 2] :owner/none,
;; More associations ...
[2 0] :owner/none},
:player :owner/cross},
{:board {[0 1] :owner/none,
[0 0] :owner/cross,
;; More associations ...
[2 0] :owner/none},
:player :owner/circle}]
(defn render-cell
"Dispatch the rendering of the cell based on the player"
[[coord owner :as cell] on-move]
(let [renderer (case owner
:owner/cross render-cross
:owner/circle render-circle
render-square)]
(renderer coord {:on-click #(on-move coord)})))
(def size "The size of the board" 3)
(def coordinates
"All the valid coordinates on the board"
(for [x (range size) y (range size)] [x y]))
(def coordinates? (set coordinates))
(def empty-board (zipmap coordinates (repeat :owner/none)))