decent support for server-side powered analysis, without variations

This commit is contained in:
Thibault Duplessis 2015-05-04 19:33:11 +02:00
parent 2abb0f89ef
commit 32799ec15e
6 changed files with 37 additions and 40 deletions

View file

@ -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))

View file

@ -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) {

View file

@ -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);
}
}
});

View file

@ -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);

View file

@ -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));

View file

@ -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'
};