improve puzzle frontend
This commit is contained in:
parent
748213beb4
commit
17a4f8803f
19
app/views/puzzle/infoBox.scala.html
Normal file
19
app/views/puzzle/infoBox.scala.html
Normal 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>
|
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)))))))))
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue