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

View File

@ -10,15 +10,15 @@ var EVAL_REGEX = new RegExp(''
module.exports = function(worker, opts) {
var emitTimer = null;
var work = null;
var state = null;
var curEval = null;
var stopped = m.deferred();
stopped.resolve(true);
var emit = function() {
emitTimer = clearTimeout(emitTimer);
if (!work || !state) return;
work.emit(state);
if (!work || !curEval) return;
work.emit(curEval);
};
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.
// The exception is for multiPV, sometimes non-primary PVs
// 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 = {
best: pv.split(' ', 2)[0],
@ -68,26 +68,25 @@ module.exports = function(worker, opts) {
};
if (multiPv === 1) {
state = {
work: work,
eval: {
depth: depth,
nps: nps,
best: pvData.best,
cp: pvData.cp,
mate: pvData.mate,
pvs: [pvData],
millis: elapsedMs,
},
curEval = {
fen: work.currentFen,
maxDepth: work.maxDepth,
depth: depth,
nps: nps,
best: pvData.best,
cp: pvData.cp,
mate: pvData.mate,
pvs: [pvData],
millis: elapsedMs,
};
} else if (state) {
state.eval.pvs.push(pvData);
state.eval.depth = Math.min(state.eval.depth, depth);
} else if (curEval) {
curEval.pvs.push(pvData);
curEval.depth = Math.min(curEval.depth, depth);
}
if (multiPv === work.multiPv) {
emit();
state = null;
curEval = null;
} else {
// emit timeout in case there aren't a full set of PVs.
clearTimeout(emitTimer);
@ -98,7 +97,7 @@ module.exports = function(worker, opts) {
return {
start: function(w) {
work = w;
state = null;
curEval = null;
stopped = null;
minLegalMoves = 0;
if (opts.threads) worker.send('setoption name Threads value ' + opts.threads());

View File

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