improve puzzle frontend

This commit is contained in:
Thibault Duplessis 2014-02-05 21:18:15 +01:00
parent 748213beb4
commit 17a4f8803f
8 changed files with 83 additions and 50 deletions

View file

@ -0,0 +1,19 @@
@(puzzle: lila.puzzle.Puzzle)(implicit ctx: Context)
<div class="lichess_goodies">
<div class="box">
<h1>Puzzle</h1>
<p>
Rating: <strong>@puzzle.rating.intRating</strong> <small title="Glicko rating deviation"> ±@puzzle.rating.intDeviationDoubled</small>
</p>
<p>
Played <strong>@puzzle.attempts</strong> times
</p>
<p>
Win rate: <strong>@puzzle.winPercent</strong>%
</p>
<p>
Average solving time: <strong>@puzzle.time</strong> seconds
</p>
</div>
</div>

View file

@ -1,4 +1,4 @@
@(title: String, evenMoreCss: Option[Html] = None, evenMoreJs: Option[Html] = None)(body: Html)(implicit ctx: Context)
@(title: String, goodies: Option[Html] = None, evenMoreCss: Option[Html] = None, evenMoreJs: Option[Html] = None)(body: Html)(implicit ctx: Context)
@moreCss = {
@cssTag("puzzle.css")
@ -11,6 +11,7 @@
@base.layout(
title = title,
goodies = goodies,
moreCss = moreCss,
moreJs = moreJs,
active = siteMenu.puzzle.some) {

View file

@ -11,38 +11,35 @@
}
@layout("Puzzle " + puzzle.id,
goodies = infoBox(puzzle).some,
evenMoreCss = moreCss.some,
evenMoreJs = moreJs.some) {
<div class="content_box">
<div id="puzzle">
<div id="puzzle">
<h1>Puzzle #@puzzle.id</h1>
<p><a href="@routes.Puzzle.home">Back to puzzle list</a></p>
<div id="chessboard"
data-post-url="@routes.Puzzle.attempt(puzzle.id)"
data-fen="@puzzle.fen"
data-color="@puzzle.color"
data-move="@puzzle.initialMove"
data-lines="@lila.puzzle.Line.toJsonString(puzzle.lines)"></div>
<div id="chessboard"
data-fen="@puzzle.fen"
data-color="@puzzle.color"
data-move="@puzzle.initialMove"
data-lines="@lila.puzzle.Line.toJsonString(puzzle.lines)"></div>
@puzzle.gameId.map { id =>
<p><a href="@routes.Round.watcher(id, puzzle.color.name)">From game #@id</a></p>
}
@puzzle.gameId.map { id =>
<p><a href="@routes.Round.watcher(id, puzzle.color.name)">From game #@id</a></p>
}
<div class="message on_win">
Congratulations! You solved the puzzle.
</div>
<div class="message on_retry">
This was a good move, but you can do better!
</div>
<div class="message on_fail">
Puzzle failed! But you can keep looking for the solution.
</div>
<div class="message on_win">
Congratulations! You solved the puzzle.
</div>
<div class="message on_retry">
This was a good move, but you can do better!
</div>
<div class="message on_fail">
Puzzle failed! But you can keep looking for the solution.
</div>
<pre>
@lila.puzzle.Line.toString(puzzle.lines)
</pre>
</div>
</div>
}

View file

@ -3,8 +3,9 @@
:source-paths ["src-clj"]
:dependencies [[org.clojure/clojure "1.5.1"]
[org.clojure/clojurescript "0.0-2156" :exclusions [org.apache.ant/ant]]
[org.clojure/core.async "0.1.267.0-0d7780-alpha"]
[prismatic/dommy "0.1.2"]
[org.clojure/core.async "0.1.267.0-0d7780-alpha"]]
[cljs-ajax "0.2.3"]]
:plugins [[lein-cljsbuild "1.0.2"]]
:cljsbuild {
:builds {

View file

@ -1,5 +1,6 @@
(ns lichess.puzzle
(:require [dommy.core :as dommy]
[ajax.core :as xhr]
[cljs.core.async :as async :refer [chan <! >! alts! put! close! timeout]])
(:require-macros [cljs.core.async.macros :refer [go]])
(:use-macros [dommy.macros :only [sel sel1]]))
@ -12,6 +13,7 @@
(def chessboard-elem (sel1 "#chessboard"))
(def initial-fen (dommy/attr chessboard-elem "data-fen"))
(def initial-move (dommy/attr chessboard-elem "data-move"))
(def post-url (dommy/attr chessboard-elem "data-post-url"))
(def lines (js->clj (js/JSON.parse (dommy/attr chessboard-elem "data-lines"))))
(def drop-chan (chan))
(def animation-delay 300)
@ -66,14 +68,15 @@
(defn set-status! [status] (dommy/set-attr! puzzle-elem :class status))
(defn post-attempt! []
(log! "post attempt!"))
(defn end! [status]
(set-status! status))
(defn fail! []
(set-status! "playing fail"))
(defn fail! [retries]
(set-status! "playing fail")
(xhr/POST post-url {:win 0
:hints 0
:retries 0
:time (seconds-since-started)}))
(go
(<! (timeout 1000))
@ -83,6 +86,7 @@
(set-status! "playing")
(loop [progress []
fen (.fen chess)
retries 0
failed false]
(let [move (<! drop-chan)
new-progress (conj progress move)
@ -93,21 +97,21 @@
(<! (timeout animation-delay))
(.load chess fen)
(set-position! fen)
(recur progress fen failed))
(recur progress fen (+ 1 retries) failed))
nil (do
(when (not failed) (fail!)
(<! (timeout animation-delay))
(.load chess fen)
(set-position! fen)
(recur progress fen true))
(do
(set-status! "playing")
(color-move! move)
(set-position! (.fen chess))
(<! (timeout (+ animation-delay 50)))
(if (= new-lines "win")
(end! "win")
(let [aim (<! (ai-play! new-lines))]
(if (= (get new-lines aim) "win")
(end! "win")
(recur (conj new-progress aim) (.fen chess) failed)))))))))
(when (not failed) (fail! retries))
(<! (timeout animation-delay))
(.load chess fen)
(set-position! fen)
(recur progress fen retries true))
(do
(set-status! "playing")
(color-move! move)
(set-position! (.fen chess))
(<! (timeout (+ animation-delay 50)))
(if (= new-lines "win")
(end! "win")
(let [aim (<! (ai-play! new-lines))]
(if (= (get new-lines aim) "win")
(end! "win")
(recur (conj new-progress aim) (.fen chess) retries failed)))))))))

View file

@ -22,6 +22,8 @@ case class Puzzle(
wins: Int,
time: Int) {
def winPercent = if (attempts == 0) 0 else wins * 100 / attempts
def initialMove = history.last
}

View file

@ -41,7 +41,7 @@ object HistoryRepo {
)).void
private val arrayReader = implicitly[BSONReader[_ <: BSONValue, BSONArray]].asInstanceOf[BSONReader[BSONValue, BSONArray]]
def userRatings(userId: String, slice: Option[Int] = None): Fu[List[HistoryEntry]] = {
def userRatings(userId: String, slice: Option[Int] = None): Fu[List[HistoryEntry]] =
historyColl.find(
BSONDocument("_id" -> userId),
BSONDocument("_id" -> false) ++ slice.fold(BSONDocument()) { s
@ -61,5 +61,4 @@ object HistoryRepo {
}
} yield elems.toList)
}
}
}

View file

@ -1,6 +1,5 @@
#chessboard {
width: 520px;
margin: 20px auto;
}
#puzzle .on_win,
@ -31,3 +30,14 @@
.last {
background-image: url(../images/over5.png);
}
.lichess_goodies h1 {
text-align: center;
font-size: 1.4em;
font-weight: bold;
padding-bottom: 8px;
border-bottom: 1px solid #3d3d3d;
margin-bottom: 8px;
}
.lichess_goodies p {
line-height: 1.8em;
}