diff --git a/modules/api/src/main/RoundApi.scala b/modules/api/src/main/RoundApi.scala index 26cae9cddb..c542990d33 100644 --- a/modules/api/src/main/RoundApi.scala +++ b/modules/api/src/main/RoundApi.scala @@ -92,43 +92,38 @@ private[api] final class RoundApi( analysis: Analysis, variant: Variant, possibleMoves: Boolean): List[Step] = - analysis.advices.pp.foldLeft(steps.pp) { + analysis.advices.foldLeft(steps) { case (steps, ad) => (for { before <- steps lift (ad.ply - 1) after <- steps lift ad.ply } yield steps.updated(ad.ply, after.copy( nag = ad.nag.symbol.some, - comments = ad.makeComment(true, true) :: step.comments, - variations = if (ad.info.variation.isEmpty) step.variations - else makeVariation(before, ad.info, variant, possibleMoves) :: step.variations)) + comments = ad.makeComment(false, true) :: after.comments, + variations = if (ad.info.variation.isEmpty) after.variations + else makeVariation(before, ad.info, variant, possibleMoves) :: after.variations)) ) | steps } private def makeVariation(fromStep: Step, info: Info, variant: Variant, possibleMoves: Boolean): List[Step] = - try { - chess.Replay.boards( - info.pp.variation take 20, - fromStep.pp.fen.some, - variant, - info.color - ).err.drop(1).pp.zipWithIndex.map { - case (board, i) => - val ply = info.ply + i - var color = chess.Color(ply % 2 == 0) - Step( - ply = ply, - move = for { - pos <- board.history.lastMove - san <- info.variation lift i - } yield Step.Move(pos, san), - fen = Forsyth exportBoard board, - check = board check color, - dests = possibleMoves ?? chess.Situation(board, color).destinations) - } - } - catch { - case e: Exception => Nil - } + chess.Replay.boards( + info.variation take 20, + fromStep.fen.some, + variant, + info.color + ).err.drop(1).zipWithIndex.map { + case (board, i) => + val ply = info.ply + i + var color = chess.Color(ply % 2 == 0) + Step( + ply = ply, + move = for { + pos <- board.history.lastMove + san <- info.variation lift i + } yield Step.Move(pos, san), + fen = Forsyth exportBoard board, + check = board check color, + dests = possibleMoves ?? chess.Situation(board, color).destinations) + } private def withNote(note: String)(json: JsObject) = if (note.isEmpty) json else json + ("note" -> JsString(note)) diff --git a/ui/analyse/src/analyse.js b/ui/analyse/src/analyse.js index 6681faa163..89dcfd09f4 100644 --- a/ui/analyse/src/analyse.js +++ b/ui/analyse/src/analyse.js @@ -53,6 +53,7 @@ module.exports = function(steps, analysis) { } }); if (curMove) { + curMove.variations = curMove.variations || []; if (curMove.san == san) return nextPath; for (var i = 0; i < curMove.variations.length; i++) { if (curMove.variations[i][0].san == san) { diff --git a/ui/analyse/src/control.js b/ui/analyse/src/control.js index 86d6e1b29e..8c28736477 100644 --- a/ui/analyse/src/control.js +++ b/ui/analyse/src/control.js @@ -1,4 +1,5 @@ var path = require('./path'); +var empty = require('./util').empty; function canGoForward(ctrl) { var tree = ctrl.analyse.tree; @@ -25,7 +26,7 @@ function canEnterVariation(ctrl) { if (step.variation) { tree = move.variations[step.variation - 1]; break; - } else ok = move.variations.length > 0; + } else ok = !empty(move.variations); } } }); diff --git a/ui/round/src/ctrl.js b/ui/round/src/ctrl.js index 43a3e3bac5..abf914a061 100644 --- a/ui/round/src/ctrl.js +++ b/ui/round/src/ctrl.js @@ -25,7 +25,7 @@ module.exports = function(opts) { this.userId = opts.userId; this.vm = { - ply: this.data.game.steps.length - 1, + ply: this.data.steps.length - 1, flip: false, reloading: false, redirecting: false, @@ -51,7 +51,7 @@ module.exports = function(opts) { this.chessground = ground.make(this.data, opts.data.game.fen, onUserMove, onMove); this.replaying = function() { - return this.vm.ply !== this.data.game.steps.length - 1; + return this.vm.ply !== this.data.steps.length - 1; }.bind(this); this.stepsHash = function(steps) { @@ -63,10 +63,10 @@ module.exports = function(opts) { }; this.jump = function(ply) { - var nbSteps = this.data.game.steps.length; + var nbSteps = this.data.steps.length; if (ply < 0 || ply >= nbSteps) return; this.vm.ply = ply; - var s = this.data.game.steps[this.vm.ply]; + var s = this.data.steps[this.vm.ply]; var config = { fen: s.fen, lastMove: s.uci ? [s.uci.substr(0, 2), s.uci.substr(2, 2)] : null, @@ -121,7 +121,7 @@ module.exports = function(opts) { this.chessground.apiMove(o.from, o.to); } if (this.data.game.threefold) this.data.game.threefold = false; - this.data.game.steps.push({ + this.data.steps.push({ fen: o.fen, san: o.san, uci: o.uci, @@ -135,8 +135,8 @@ module.exports = function(opts) { this.reload = function(cfg) { m.startComputation(); - if (this.stepsHash(cfg.game.steps) !== this.stepsHash(this.data.game.steps)) - this.vm.ply = cfg.game.steps.length - 1; + if (this.stepsHash(cfg.steps) !== this.stepsHash(this.data.steps)) + this.vm.ply = cfg.steps.length - 1; this.data = data(this.data, cfg); makeCorrespondenceClock(); if (this.clock) this.clock.update(this.data.clock.white, this.data.clock.black); diff --git a/ui/round/src/keyboard.js b/ui/round/src/keyboard.js index 3377a9e020..e289899592 100644 --- a/ui/round/src/keyboard.js +++ b/ui/round/src/keyboard.js @@ -38,7 +38,7 @@ module.exports = { m.redraw(); })); k.bind(['down', 'j'], preventing(function() { - ctrl.jump(ctrl.data.game.steps.length); + ctrl.jump(ctrl.data.steps.length - 1); m.redraw(); })); k.bind('f', preventing(ctrl.flip)); diff --git a/ui/round/src/view/replay.js b/ui/round/src/view/replay.js index 78f56a556d..4d79c19162 100644 --- a/ui/round/src/view/replay.js +++ b/ui/round/src/view/replay.js @@ -47,7 +47,7 @@ function renderResult(ctrl, asTable) { } function renderTable(ctrl) { - var steps = ctrl.data.game.steps; + var steps = ctrl.data.steps; var nbSteps = steps.length; if (!nbSteps) return; var pairs = []; @@ -74,7 +74,7 @@ function renderTable(ctrl) { } function renderButtons(ctrl) { - var nbSteps = ctrl.data.game.steps.length; + var nbSteps = ctrl.data.steps.length; var flipAttrs = { class: 'button flip hint--top' + (ctrl.vm.flip ? ' active' : ''), 'data-hint': ctrl.trans('flipBoard'), @@ -112,7 +112,7 @@ function autoScroll(movelist) { } module.exports = function(ctrl) { - var h = ctrl.vm.ply + ctrl.stepsHash(ctrl.data.game.steps) + ctrl.vm.flip; + var h = ctrl.vm.ply + ctrl.stepsHash(ctrl.data.steps) + ctrl.vm.flip; if (ctrl.vm.replayHash === h) return { subtree: 'retain' };