Partially implement game time stats
parent
f0a132f8c3
commit
115af471b2
|
@ -0,0 +1,21 @@
|
|||
package lila
|
||||
package analyse
|
||||
|
||||
import game.{ DbPlayer, DbGame }
|
||||
|
||||
import scala.math.round
|
||||
import com.codahale.jerkson.Json
|
||||
|
||||
final class TimeChart(game: DbGame) {
|
||||
|
||||
def columns = Json generate {
|
||||
List("string", "Move") :: game.players.map(p ⇒
|
||||
List("number", "%s - %s".format(p.color, p.userId | "anonymous")))
|
||||
}
|
||||
|
||||
def rows = Json generate {
|
||||
(game.creator.moveTimeList zip game.invited.moveTimeList).zipWithIndex map {
|
||||
case ((black, white), move) ⇒ List(move.toString, white, black)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package controllers
|
|||
|
||||
import lila._
|
||||
import views._
|
||||
import analyse._
|
||||
|
||||
import play.api.mvc._
|
||||
|
||||
|
@ -16,5 +17,11 @@ object Analyse extends LilaController {
|
|||
}
|
||||
}
|
||||
|
||||
def stats(id: String) = todo
|
||||
def stats(id: String) = Open { implicit ctx ⇒
|
||||
IOptionOk(gameRepo game id) { game ⇒
|
||||
html.analyse.stats(
|
||||
game = game,
|
||||
timeChart = new TimeChart(game))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,4 @@ object ForumTopic extends LilaController with forum.Controller {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
def delete(id: String) = TODO
|
||||
}
|
||||
|
|
|
@ -51,6 +51,8 @@ case class DbGame(
|
|||
def player(user: User): Option[DbPlayer] =
|
||||
players find (_ isUser user)
|
||||
|
||||
def player(c: Color.type => Color): DbPlayer = player(c(Color))
|
||||
|
||||
def isPlayerFullId(player: DbPlayer, fullId: String): Boolean =
|
||||
(fullId.size == DbGame.fullIdSize) && player.id == (fullId drop 8)
|
||||
|
||||
|
@ -295,7 +297,7 @@ case class DbGame(
|
|||
|
||||
def invitedColor = !creatorColor
|
||||
|
||||
def invited = opponent(invitedColor)
|
||||
def invited = player(invitedColor)
|
||||
|
||||
def pgnList = pgn.split(' ').toList
|
||||
|
||||
|
|
|
@ -48,6 +48,9 @@ case class DbPlayer(
|
|||
|
||||
def hasMoveTimes = moveTimes.size > 10
|
||||
|
||||
def moveTimeList: List[Int] =
|
||||
moveTimes.split(" ").toList map parseIntOption flatten
|
||||
|
||||
def finish(winner: Boolean) = copy(
|
||||
isWinner = if (winner) Some(true) else None
|
||||
)
|
||||
|
|
|
@ -14,5 +14,9 @@ final class Cached(userRepo: UserRepo) {
|
|||
(userRepo username userId).unsafePerformIO
|
||||
)
|
||||
|
||||
def usernameOrAnonymous(userId: String) = username(userId) | User.anonymous
|
||||
def usernameOrAnonymous(userId: String): String =
|
||||
username(userId) | User.anonymous
|
||||
|
||||
def usernameOrAnonymous(userId: Option[String]): String =
|
||||
userId.fold(usernameOrAnonymous, User.anonymous)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
@(game: DbGame, timeChart: lila.analyse.TimeChart)(implicit ctx: Context)
|
||||
|
||||
@moreCss = {
|
||||
@cssTag("gamestats.css")
|
||||
}
|
||||
|
||||
@moreJs = {
|
||||
<script src="http://www.google.com/jsapi"></script>
|
||||
@jsTag("chart.js")
|
||||
@jsTag("gamestats.js")
|
||||
}
|
||||
|
||||
@title = @{ "Game #%s time stats" format game.id }
|
||||
|
||||
@analyse.layout(
|
||||
title = title,
|
||||
moreCss = moreCss,
|
||||
moreJs = moreJs) {
|
||||
<div class="content_box">
|
||||
<h1 class="title">
|
||||
Game <a href="@routes.Round.watcher(game.id, "white")">#@game.id</a> time stats
|
||||
</h1>
|
||||
<br /><br />
|
||||
<div
|
||||
class="move-time"
|
||||
data-title="Time per move evolution"
|
||||
data-columns="@timeChart.columns"
|
||||
data-rows="@timeChart.rows"></div>
|
||||
</div>
|
||||
}
|
|
@ -1,30 +1,30 @@
|
|||
.title {
|
||||
font-size: 1.8em;
|
||||
color: #666;
|
||||
font-weight: normal;
|
||||
margin-bottom: 0.5em;
|
||||
font-size: 1.8em;
|
||||
color: #666;
|
||||
font-weight: normal;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 1.6em;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
margin: 1.5em 0;
|
||||
border-top: 1px solid #dadada;
|
||||
padding: 0.5em 0;
|
||||
text-align: right;
|
||||
font-size: 1.6em;
|
||||
color: #999;
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
margin: 1.5em 0;
|
||||
border-top: 1px solid #dadada;
|
||||
padding: 0.5em 0;
|
||||
text-align: right;
|
||||
}
|
||||
.chart-title {
|
||||
font-size: 1.4em;
|
||||
color: #666;
|
||||
font-weight: normal;
|
||||
margin-bottom: 0.5em;
|
||||
font-size: 1.4em;
|
||||
color: #666;
|
||||
font-weight: normal;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
.half {
|
||||
float: left;
|
||||
width: 49%;
|
||||
margin-right: 2%;
|
||||
float: left;
|
||||
width: 49%;
|
||||
margin-right: 2%;
|
||||
}
|
||||
.half.last {
|
||||
margin-right: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
|
1
todo
1
todo
|
@ -19,6 +19,7 @@ endgame sound http://en.lichess.org/forum/lichess-feedback/checkmate-sound-featu
|
|||
translation contributions
|
||||
check sf2 commands to port
|
||||
make the wiki static html pages managed by git?
|
||||
compensate lag http://fr.lichess.org/forum/lichess-feedback/the-clock-display-should-account-for-lag?page=1#4
|
||||
|
||||
next deploy:
|
||||
bin/migrate
|
||||
|
|
Loading…
Reference in New Issue