Last active
August 29, 2015 13:56
-
-
Save rm-hull/8906851 to your computer and use it in GitHub Desktop.
OM version of Garry Kasparov - Veselin Topalov ; Hoogovens A Tournament Wijk aan Zee NED 1999.01.20 - adapted from https://raw2.github.com/danieroux/rubyfuza2014/master/src/rubyfuza/core.cljs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Adapted from https://raw2.github.com/danieroux/rubyfuza2014/master/src/rubyfuza/core.cljs | |
(ns rubyfuza.core | |
(:require-macros | |
[cljs.core.async.macros :refer [go]]) | |
(:require | |
[clojure.string :as str] | |
[om.core :as om :include-macros true] | |
[om.dom :as dom :include-macros true] | |
[cljs.core.async :as async :refer [put! chan <! >! timeout]])) | |
;;; Setup | |
(def pieces | |
{"BR" "♜" | |
"BK" "♞" | |
"BB" "♝" | |
"BQ" "♛" | |
"BG" "♚" | |
"BP" "♟" | |
"WR" "♖" | |
"WK" "♘" | |
"WB" "♗" | |
"WQ" "♕" | |
"WG" "♔" | |
"WP" "♙"}) | |
(def starting-board | |
[["BR", "BK", "BB", "BQ", "BG", "BB", "BK", "BR"] ;; A8 - H8 | |
["BP", "BP", "BP", "BP", "BP", "BP", "BP", "BP"] | |
["" , "" , "" , "" , "" , "" , "" , ""] | |
["" , "" , "" , "" , "" , "" , "" , ""] | |
["" , "" , "" , "" , "" , "" , "" , ""] | |
["" , "" , "" , "" , "" , "" , "" , ""] | |
["WP", "WP", "WP", "WP", "WP", "WP", "WP", "WP"] | |
["WR", "WK", "WB", "WQ", "WG", "WB", "WK", "WR"]]) | |
;;; Logic | |
(def col-map {"a" 0 "b" 1 "c" 2 "d" 3 "e" 4 "f" 5 "g" 6 "h" 7}) | |
(defn coords-from [square] | |
(let [column (get col-map (first square)) | |
parsed-row (js/parseInt (last square)) | |
row (- 8 parsed-row)] | |
[row column])) | |
(defn move [board from-square to-square] | |
"Returns an updated board with the move made" | |
(let [from-coords (coords-from from-square) | |
to-coords (coords-from to-square) | |
from-piece (get-in board from-coords)] | |
(-> board | |
(assoc-in to-coords from-piece) | |
(assoc-in from-coords "")))) | |
;;; Rendering | |
(defn style [& styles] | |
(dom/style nil (str/join \newline styles))) | |
(defn draw-square [square] | |
(dom/td nil square)) | |
(defn draw-row [row] | |
(apply dom/tr nil | |
(map draw-square row))) | |
(defn unicode-pieces [board] | |
(for [row board] | |
(map #(get pieces % "") row))) | |
(defn board [board owner] | |
(om/component | |
(apply | |
dom/table | |
#js {:className "chess_board"} | |
(style | |
".chess_board tr:nth-child(even) td:nth-child(odd), | |
.chess_board tr:nth-child(odd) td:nth-child(even) { | |
background: white; | |
box-shadow: inset 0 0 10px rgba(0,0,0,.4); | |
-moz-box-shadow: inset 0 0 10px rgba(0,0,0,.4); | |
-webkit-box-shadow: inset 0 0 10px rgba(0,0,0,.4); | |
} | |
.chess_board td { | |
background: red; | |
width: 60px; height: 60px; | |
font-size: 40px; | |
color: black; | |
text-align: center; | |
}") | |
(let [unicoded-board (unicode-pieces board)] | |
(map draw-row unicoded-board))))) | |
;;; State | |
(def app-state (atom {:board starting-board})) | |
(def app-history (atom [@app-state])) | |
(defn start-chess! [] | |
(om/root | |
app-state | |
(fn [app owner] | |
(om/build board (:board app))) | |
(. js/document (getElementById "app")))) | |
(defn reset-and-start-chess! [] | |
(reset! app-state {:board starting-board}) | |
(reset! app-history [@app-state]) | |
(start-chess!)) | |
(defn move! [from-square to-square] | |
(swap! app-state | |
update-in [:board] move from-square to-square) | |
(swap! app-history | |
conj @app-state)) | |
;;; World interaction | |
(def the-world (chan)) | |
(defn server-says [move-string] | |
(let [from-square (subs move-string 0 2) | |
to-square (subs move-string 2)] | |
(move! from-square to-square))) | |
(defn assimilate-novelty [world-channel] | |
(go (while true | |
(if-let [move-string (<! world-channel)] | |
(server-says move-string))))) | |
(defn replay-game [world-channel moves] | |
(dorun (map #(put! world-channel %) moves))) | |
;;; Playing with history | |
(defn show-move! [move-number] | |
(reset! app-state (nth @app-history move-number))) | |
(defn slideshow [start finish] | |
(go | |
(doseq [step (range start finish)] | |
(do | |
(show-move! step) | |
(<! (timeout 150)))))) | |
(defn cycle-every-state [] | |
;; Show that react.js only renders when it needs to | |
(doseq [step (range 0 (count @app-history))] | |
(show-move! step))) | |
;;; Main | |
; Start listening to changes in the world | |
(assimilate-novelty the-world) | |
;;; Demo | |
; Garry Kasparov - Veselin Topalov | |
; Hoogovens A Tournament Wijk aan Zee NED 1999.01.20 | |
(defn kasparov-topalov [the-world] | |
(let [moves ["e2e4" "d7d6" "d2d4" "g8f6" "b1c3" "g7g6" "c1e3" "f8g7" "d1d2" "c7c6" "f2f3" "b7b5" "g1e2" "b8d7" "e3h6" "g7h6" "d2h6" "c8b7" "a2a3" "e7e5" "e1c1" "d8e7" "c1b1" "a7a6" "e2c1" "e8c8" "c1b3" "e5d4" "d1d4" "c6c5" "d4d1" "d7b6" "g2g3" "c8b8" "b3a5" "b7a8" "f1h3" "d6d5" "h6f4" "b8a7" "h1e1" "d5d4" "c3d5" "b6d5" "e4d5" "e7d6" "d1d4" "c5d4" "e1e7" "a7b6" "f4d4" "b6a5" "b2b4" "a5a4" "d4c3" "d6d5" "e7a7" "a8b7" "a7b7" "d5c4" "c3f6" "a4a3" "f6a6" "a3b4" "c2c3" "b4c3" "a6a1" "c3d2" "a1b2" "d2d1" "h3f1" "d8d2" "b7d7" "d2d7" "f1c4" "b5c4" "b2h8" "d7d3" "h8a8" "c4c3" "a8a4" "d1e1" "f3f4" "f7f5" "b1c1" "d3d2" "a4a7"]] | |
(replay-game the-world moves))) | |
(defn run-demo [] | |
(reset-and-start-chess!) | |
(kasparov-topalov the-world) | |
(go | |
(slideshow 0 (count @app-history)))) | |
(set! (.-onload js/window) run-demo) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment