Condense ceval emit objects

Convert emit(state) to emit(eval, work) to
simplify logic.
pull/2559/head
Isaac Levy 2017-01-22 18:42:03 -05:00
parent c5686ad2a6
commit a363688bc4
4 changed files with 59 additions and 64 deletions

View File

@ -440,14 +440,14 @@ module.exports = function(opts) {
possible: !this.embed && ( possible: !this.embed && (
util.synthetic(this.data) || !game.playable(this.data) util.synthetic(this.data) || !game.playable(this.data)
), ),
emit: function(res) { emit: function(eval, work) {
this.tree.updateAt(res.work.path, function(node) { this.tree.updateAt(work.path, function(node) {
if (res.work.threatMode) { if (work.threatMode) {
if (!node.threat || node.threat.depth < res.eval.depth || node.threat.maxDepth < res.eval.maxDepth) if (!node.threat || node.threat.depth <= eval.depth || node.threat.maxDepth < eval.maxDepth)
node.threat = res.eval; node.threat = eval;
} else if (!node.ceval || node.ceval.depth < res.eval.depth || node.ceval.maxDepth < res.eval.maxDepth) } else if (!node.ceval || node.ceval.depth <= eval.depth || node.ceval.maxDepth < eval.maxDepth)
node.ceval = res.eval; node.ceval = eval;
if (res.work.path === this.vm.path) { if (work.path === this.vm.path) {
this.setAutoShapes(); this.setAutoShapes();
if (this.retro) this.retro.onCeval(); if (this.retro) this.retro.onCeval();
if (this.practice) this.practice.onCeval(); if (this.practice) this.practice.onCeval();

View File

@ -17,7 +17,7 @@ module.exports = function(opts) {
var multiPv = storedProp(storageKey('ceval.multipv'), opts.multiPvDefault || 1); var multiPv = storedProp(storageKey('ceval.multipv'), opts.multiPvDefault || 1);
var threads = storedProp(storageKey('ceval.threads'), Math.ceil((navigator.hardwareConcurrency || 1) / 2)); var threads = storedProp(storageKey('ceval.threads'), Math.ceil((navigator.hardwareConcurrency || 1) / 2));
var hashSize = storedProp(storageKey('ceval.hash-size'), 128); var hashSize = storedProp(storageKey('ceval.hash-size'), 128);
var curDepth = 0; var curEval = null;
var enableStorage = lichess.storage.make(storageKey('client-eval-enabled')); var enableStorage = lichess.storage.make(storageKey('client-eval-enabled'));
var allowed = m.prop(true); var allowed = m.prop(true);
var enabled = m.prop(opts.possible && allowed() && enableStorage.get() == '1' && !document.hidden); var enabled = m.prop(opts.possible && allowed() && enableStorage.get() == '1' && !document.hidden);
@ -39,14 +39,14 @@ module.exports = function(opts) {
// adjusts maxDepth based on nodes per second // adjusts maxDepth based on nodes per second
var npsRecorder = (function() { var npsRecorder = (function() {
var values = []; var values = [];
var applies = function(res) { var applies = function(eval) {
return res.eval.nps && res.eval.depth >= 16 && return eval.nps && eval.depth >= 16 &&
!res.eval.mate && Math.abs(res.eval.cp) < 500 && !eval.mate && Math.abs(eval.cp) < 500 &&
(res.work.currentFen.split(/\s/)[0].split(/[nbrqkp]/i).length - 1) >= 10; (eval.fen.split(/\s/)[0].split(/[nbrqkp]/i).length - 1) >= 10;
} }
return function(res) { return function(eval) {
if (!applies(res)) return; if (!applies(eval)) return;
values.push(res.eval.nps); values.push(eval.nps);
if (values.length >= 5) { if (values.length >= 5) {
var depth = 18, var depth = 18,
knps = median(values) / 1000; knps = median(values) / 1000;
@ -64,16 +64,15 @@ module.exports = function(opts) {
}; };
})(); })();
var onEmit = function(res) { var onEmit = function(eval, work) {
res.eval.maxDepth = res.work.maxDepth; npsRecorder(eval);
npsRecorder(res); curEval = eval;
curDepth = res.eval.depth; opts.emit(eval, work);
opts.emit(res); publish(eval);
publish(res);
}; };
var publish = function(res) { var publish = function(eval) {
if (res.eval.depth === 12) lichess.storage.set('ceval.fen', res.work.currentFen); if (eval.depth === 12) lichess.storage.set('ceval.fen', eval.fen);
}; };
var start = function(path, steps, threatMode, deeper) { var start = function(path, steps, threatMode, deeper) {
@ -97,9 +96,9 @@ module.exports = function(opts) {
maxDepth: maxD, maxDepth: maxD,
multiPv: parseInt(multiPv()), multiPv: parseInt(multiPv()),
threatMode: threatMode, threatMode: threatMode,
emit: function(res) { };
if (enabled()) onEmit(res); work.emit = function(eval) {
} if (enabled()) onEmit(eval, work);
}; };
if (threatMode) { if (threatMode) {
@ -123,14 +122,11 @@ module.exports = function(opts) {
setTimeout(function() { setTimeout(function() {
// this has to be delayed, or it slows down analysis first render. // this has to be delayed, or it slows down analysis first render.
work.emit({ work.emit({
work: work, depth: maxD,
eval: { cp: dictRes.cp,
depth: maxD, best: dictRes.best,
cp: dictRes.cp, pvs: dictRes.pvs,
best: dictRes.best, dict: true
pvs: dictRes.pvs,
dict: true
}
}); });
}, 500); }, 500);
pool.warmup(); pool.warmup();
@ -188,7 +184,7 @@ module.exports = function(opts) {
enableStorage.set(enabled() ? '1' : '0'); enableStorage.set(enabled() ? '1' : '0');
}, },
curDepth: function() { curDepth: function() {
return curDepth; return curEval ? curEval.depth : 0;
}, },
maxDepth: maxDepth, maxDepth: maxDepth,
variant: opts.variant, variant: opts.variant,

View File

@ -10,15 +10,15 @@ var EVAL_REGEX = new RegExp(''
module.exports = function(worker, opts) { module.exports = function(worker, opts) {
var emitTimer = null; var emitTimer = null;
var work = null; var work = null;
var state = null; var curEval = null;
var stopped = m.deferred(); var stopped = m.deferred();
stopped.resolve(true); stopped.resolve(true);
var emit = function() { var emit = function() {
emitTimer = clearTimeout(emitTimer); emitTimer = clearTimeout(emitTimer);
if (!work || !state) return; if (!work || !curEval) return;
work.emit(state); work.emit(curEval);
}; };
if (opts.variant.key === 'fromPosition' || opts.variant.key === 'chess960') if (opts.variant.key === 'fromPosition' || opts.variant.key === 'chess960')
@ -57,7 +57,7 @@ module.exports = function(worker, opts) {
// For now, ignore most upperbound/lowerbound messages. // For now, ignore most upperbound/lowerbound messages.
// The exception is for multiPV, sometimes non-primary PVs // The exception is for multiPV, sometimes non-primary PVs
// only have an upperbound. See: ddugovic/Stockfish#228 // only have an upperbound. See: ddugovic/Stockfish#228
if (evalType && (multiPv === 1 || evalType !== 'upper' || !state)) return; if (evalType && (multiPv === 1 || evalType !== 'upper' || !curEval)) return;
var pvData = { var pvData = {
best: pv.split(' ', 2)[0], best: pv.split(' ', 2)[0],
@ -68,26 +68,25 @@ module.exports = function(worker, opts) {
}; };
if (multiPv === 1) { if (multiPv === 1) {
state = { curEval = {
work: work, fen: work.currentFen,
eval: { maxDepth: work.maxDepth,
depth: depth, depth: depth,
nps: nps, nps: nps,
best: pvData.best, best: pvData.best,
cp: pvData.cp, cp: pvData.cp,
mate: pvData.mate, mate: pvData.mate,
pvs: [pvData], pvs: [pvData],
millis: elapsedMs, millis: elapsedMs,
},
}; };
} else if (state) { } else if (curEval) {
state.eval.pvs.push(pvData); curEval.pvs.push(pvData);
state.eval.depth = Math.min(state.eval.depth, depth); curEval.depth = Math.min(curEval.depth, depth);
} }
if (multiPv === work.multiPv) { if (multiPv === work.multiPv) {
emit(); emit();
state = null; curEval = null;
} else { } else {
// emit timeout in case there aren't a full set of PVs. // emit timeout in case there aren't a full set of PVs.
clearTimeout(emitTimer); clearTimeout(emitTimer);
@ -98,7 +97,7 @@ module.exports = function(worker, opts) {
return { return {
start: function(w) { start: function(w) {
work = w; work = w;
state = null; curEval = null;
stopped = null; stopped = null;
minLegalMoves = 0; minLegalMoves = 0;
if (opts.threads) worker.send('setoption name Threads value ' + opts.threads()); if (opts.threads) worker.send('setoption name Threads value ' + opts.threads());

View File

@ -250,14 +250,14 @@ module.exports = function(opts, i18n) {
key: 'standard' key: 'standard'
}, },
possible: true, possible: true,
emit: function(res) { emit: function(eval, work) {
tree.updateAt(res.work.path, function(node) { tree.updateAt(work.path, function(node) {
if (res.work.threatMode) { if (work.threatMode) {
if (!node.threat || node.threat.depth < res.eval.depth || node.threat.maxDepth < res.eval.maxDepth) if (!node.threat || node.threat.depth <= eval.depth || node.threat.maxDepth < eval.maxDepth)
node.threat = res.eval; node.threat = eval;
} else if (!node.ceval || node.ceval.depth < res.eval.depth || node.ceval.maxDepth < res.eval.maxDepth) } else if (!node.ceval || node.ceval.depth <= eval.depth || node.ceval.maxDepth < eval.maxDepth)
node.ceval = res.eval; node.ceval = eval;
if (res.work.path === vm.path) { if (work.path === vm.path) {
setAutoShapes(); setAutoShapes();
m.redraw(); m.redraw();
} }