tictactoe
This commit is contained in:
parent
dd58d814d5
commit
fd5acb9164
87
resources/public/cljs/tictactoe.cljs
Normal file
87
resources/public/cljs/tictactoe.cljs
Normal file
|
@ -0,0 +1,87 @@
|
|||
(ns tictactoe
|
||||
"Ported from https://github.com/borkdude/tictactoe-cljs"
|
||||
(:require [reagent.core :as r]
|
||||
[reagent.dom :as rdom]))
|
||||
|
||||
(defn foo [] (< 1 2))
|
||||
|
||||
(def empty-board [[\- \- \-]
|
||||
[\- \- \-]
|
||||
[\- \- \-]])
|
||||
|
||||
(def state (r/atom {:board empty-board :player \X}))
|
||||
|
||||
(defn get-board-cell
|
||||
([board row col]
|
||||
(get-in board [row col])))
|
||||
|
||||
(defn get-player [app-state]
|
||||
(-> app-state :game-state :player))
|
||||
|
||||
(defn other-player [player]
|
||||
(if (= player \X) \O \X))
|
||||
|
||||
(defn winner-in-rows? [board player]
|
||||
(boolean (some (fn [row] (every? (fn [c] (= c player)) row)) board)))
|
||||
|
||||
(defn transposed-board [board]
|
||||
(vec (apply map vector board)))
|
||||
|
||||
(defn winner-in-cols? [board player]
|
||||
(winner-in-rows? (transposed-board board) player))
|
||||
|
||||
(defn winner-in-diagonals? [board player]
|
||||
(let [diag-coords [[[0 0] [1 1] [2 2]]
|
||||
[[0 2] [1 1] [2 0]]]]
|
||||
(boolean (some (fn [coords]
|
||||
(every? (fn [coord]
|
||||
(= player (apply get-board-cell board coord)))
|
||||
coords))
|
||||
diag-coords))))
|
||||
|
||||
(defn winner?
|
||||
"checks if there is a winner. when called with no args, checks for player X and player O.
|
||||
returns the character for the winning player, nil if there is no winner"
|
||||
([board]
|
||||
(boolean (or (winner? board \X)
|
||||
(winner? board \O))))
|
||||
([board player]
|
||||
(when (or (winner-in-rows? board player)
|
||||
(winner-in-cols? board player)
|
||||
(winner-in-diagonals? board player))
|
||||
player)))
|
||||
|
||||
(defn full-board?
|
||||
[board]
|
||||
(let [all-cells (apply concat board)]
|
||||
(not-any? #(= % \-) all-cells)))
|
||||
|
||||
(defn new-state [old-state row col]
|
||||
(if (and (= (get-board-cell (:board old-state) row col) \-)
|
||||
(not (winner? (:board old-state))))
|
||||
{:board (assoc-in (:board old-state) [row col] (:player old-state))
|
||||
:player (other-player (:player old-state))}
|
||||
old-state))
|
||||
|
||||
(defn tictactoe []
|
||||
[:div
|
||||
(if (winner? (:board @state))
|
||||
(str "The winner is " (other-player (:player @state)))
|
||||
(if (full-board? (:board @state))
|
||||
"It's a draw"
|
||||
(str "Your turn, player " (:player @state))))
|
||||
(let [board (-> @state :board)]
|
||||
[:table
|
||||
[:tbody
|
||||
(map-indexed
|
||||
(fn [i row]
|
||||
^{:key i}
|
||||
[:tr
|
||||
(map-indexed (fn [j elt]
|
||||
^{:key j}
|
||||
[:td {:on-click (fn []
|
||||
(swap! state new-state i j))}elt])
|
||||
row)])
|
||||
board)]])])
|
||||
|
||||
(rdom/render [tictactoe] (.getElementById js/document "app"))
|
|
@ -24,7 +24,6 @@
|
|||
|
||||
<script src="cljs/script.cljs" type="application/x-sci"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/highlight.min.js" type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/languages/clojure.min.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/zenburn.min.css" integrity="sha512-JPxjD2t82edI35nXydY/erE9jVPpqxEJ++6nYEoZEpX2TRsmp2FpZuQqZa+wBCen5U16QZOkMadGXHCfp+tUdg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
|
||||
</head>
|
||||
|
@ -104,6 +103,8 @@
|
|||
</script>
|
||||
</code></pre>
|
||||
|
||||
Also see a <a href="tictactoe.html">tic-tac-toe</a> demo.
|
||||
|
||||
<div id="app"></div>
|
||||
<script type="text/javascript">hljs.highlightAll();</script>
|
||||
|
||||
|
|
58
resources/public/tictactoe.html
Normal file
58
resources/public/tictactoe.html
Normal file
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="js/sci-script-tag.js" type="application/javascript"></script>
|
||||
<script src="js/sci-script-tag-plugin-reagent.js" type="application/javascript"></script>
|
||||
|
||||
<script type="application/x-sci" src="cljs/tictactoe.cljs"></script>
|
||||
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/highlight.min.js" type="text/javascript"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/languages/clojure.min.js" type="text/javascript"></script>
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.7.2/styles/zenburn.min.css" integrity="sha512-JPxjD2t82edI35nXydY/erE9jVPpqxEJ++6nYEoZEpX2TRsmp2FpZuQqZa+wBCen5U16QZOkMadGXHCfp+tUdg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
||||
<style>
|
||||
body
|
||||
{
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
div#app
|
||||
{
|
||||
color:#666;
|
||||
}
|
||||
|
||||
div#app td
|
||||
{
|
||||
width:50px;
|
||||
height:50px;
|
||||
border:1px solid #dedede;
|
||||
background:#fff;
|
||||
margin:1px;
|
||||
color:#666;
|
||||
text-align: center;
|
||||
line-height: 50px;
|
||||
}
|
||||
|
||||
div#app td:hover
|
||||
{
|
||||
cursor:pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<h1>SCI script tag: Reagent tic-tac-toe</h1>
|
||||
<div id="app"></div>
|
||||
<p>The following source was loaded from <a href="cljs/tictactoe.cljs"><tt>cljs/tictactoe.cljs</tt></a>:</p>
|
||||
<pre><code class="language-clojure" id="cljs"></code></pre>
|
||||
<script type="text/javascript">
|
||||
function setText () {
|
||||
document.getElementById("cljs").innerHTML = (this.responseText);
|
||||
hljs.highlightAll();
|
||||
}
|
||||
var oReq = new XMLHttpRequest();
|
||||
oReq.addEventListener("load", setText);
|
||||
oReq.open("GET", "cljs/tictactoe.cljs");
|
||||
oReq.send();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue