Partially implement game time stats
This commit is contained in:
parent
f0a132f8c3
commit
115af471b2
21
app/analyse/TimeChart.scala
Normal file
21
app/analyse/TimeChart.scala
Normal file
|
@ -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 lila._
|
||||||
import views._
|
import views._
|
||||||
|
import analyse._
|
||||||
|
|
||||||
import play.api.mvc._
|
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] =
|
def player(user: User): Option[DbPlayer] =
|
||||||
players find (_ isUser user)
|
players find (_ isUser user)
|
||||||
|
|
||||||
|
def player(c: Color.type => Color): DbPlayer = player(c(Color))
|
||||||
|
|
||||||
def isPlayerFullId(player: DbPlayer, fullId: String): Boolean =
|
def isPlayerFullId(player: DbPlayer, fullId: String): Boolean =
|
||||||
(fullId.size == DbGame.fullIdSize) && player.id == (fullId drop 8)
|
(fullId.size == DbGame.fullIdSize) && player.id == (fullId drop 8)
|
||||||
|
|
||||||
|
@ -295,7 +297,7 @@ case class DbGame(
|
||||||
|
|
||||||
def invitedColor = !creatorColor
|
def invitedColor = !creatorColor
|
||||||
|
|
||||||
def invited = opponent(invitedColor)
|
def invited = player(invitedColor)
|
||||||
|
|
||||||
def pgnList = pgn.split(' ').toList
|
def pgnList = pgn.split(' ').toList
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,9 @@ case class DbPlayer(
|
||||||
|
|
||||||
def hasMoveTimes = moveTimes.size > 10
|
def hasMoveTimes = moveTimes.size > 10
|
||||||
|
|
||||||
|
def moveTimeList: List[Int] =
|
||||||
|
moveTimes.split(" ").toList map parseIntOption flatten
|
||||||
|
|
||||||
def finish(winner: Boolean) = copy(
|
def finish(winner: Boolean) = copy(
|
||||||
isWinner = if (winner) Some(true) else None
|
isWinner = if (winner) Some(true) else None
|
||||||
)
|
)
|
||||||
|
|
|
@ -14,5 +14,9 @@ final class Cached(userRepo: UserRepo) {
|
||||||
(userRepo username userId).unsafePerformIO
|
(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)
|
||||||
}
|
}
|
||||||
|
|
30
app/views/analyse/stats.scala.html
Normal file
30
app/views/analyse/stats.scala.html
Normal file
|
@ -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 {
|
.title {
|
||||||
font-size: 1.8em;
|
font-size: 1.8em;
|
||||||
color: #666;
|
color: #666;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
.section-title {
|
.section-title {
|
||||||
font-size: 1.6em;
|
font-size: 1.6em;
|
||||||
color: #999;
|
color: #999;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
margin: 1.5em 0;
|
margin: 1.5em 0;
|
||||||
border-top: 1px solid #dadada;
|
border-top: 1px solid #dadada;
|
||||||
padding: 0.5em 0;
|
padding: 0.5em 0;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
.chart-title {
|
.chart-title {
|
||||||
font-size: 1.4em;
|
font-size: 1.4em;
|
||||||
color: #666;
|
color: #666;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
.half {
|
.half {
|
||||||
float: left;
|
float: left;
|
||||||
width: 49%;
|
width: 49%;
|
||||||
margin-right: 2%;
|
margin-right: 2%;
|
||||||
}
|
}
|
||||||
.half.last {
|
.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
|
translation contributions
|
||||||
check sf2 commands to port
|
check sf2 commands to port
|
||||||
make the wiki static html pages managed by git?
|
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:
|
next deploy:
|
||||||
bin/migrate
|
bin/migrate
|
||||||
|
|
Loading…
Reference in a new issue