Use Sunsetter for local crazyhouse analysis
parent
aabd656191
commit
1732078da7
|
@ -31,3 +31,6 @@
|
|||
[submodule "public/vendor/stockfish.js"]
|
||||
path = public/vendor/stockfish.js
|
||||
url = https://github.com/niklasf/stockfish.js
|
||||
[submodule "public/vendor/Sunsetter"]
|
||||
path = public/vendor/Sunsetter
|
||||
url = https://github.com/niklasf/Sunsetter.git
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 3d0122e11268a11edb9c95916f8a3fc062b8ce5c
|
|
@ -1,6 +1,8 @@
|
|||
var m = require('mithril');
|
||||
var makePool = require('./cevalPool');
|
||||
var dict = require('./cevalDict');
|
||||
var stockfishWorker = require('./stockfishWorker');
|
||||
var sunsetterWorker = require('./sunsetterWorker');
|
||||
|
||||
module.exports = function(possible, variant, emit) {
|
||||
|
||||
|
@ -12,12 +14,12 @@ module.exports = function(possible, variant, emit) {
|
|||
var allowed = m.prop(true);
|
||||
var enabled = m.prop(possible() && allowed() && lichess.storage.get(storageKey) === '1');
|
||||
var started = false;
|
||||
var engine = variant.key !== 'crazyhouse' ? stockfishWorker : sunsetterWorker;
|
||||
var pool = makePool({
|
||||
path: '/assets/vendor/stockfish.js/stockfish.js', // Can't CDN because same-origin policy
|
||||
minDepth: minDepth,
|
||||
maxDepth: maxDepth,
|
||||
variant: variant
|
||||
}, nbWorkers);
|
||||
}, engine, nbWorkers);
|
||||
|
||||
var onEmit = function(res) {
|
||||
curDepth = res.eval.depth;
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
var m = require('mithril');
|
||||
var makeWorker = require('./cevalWorker');
|
||||
|
||||
module.exports = function(opts, nb) {
|
||||
module.exports = function(opts, makeWorker, nb) {
|
||||
|
||||
var workers = [];
|
||||
var token = -1;
|
||||
|
|
|
@ -56,7 +56,7 @@ module.exports = function(opts, name) {
|
|||
|
||||
var reboot = function() {
|
||||
if (instance) instance.terminate();
|
||||
instance = new Worker(opts.path);
|
||||
instance = new Worker('/assets/vendor/stockfish.js/stockfish.js');
|
||||
busy = false;
|
||||
stopping = false;
|
||||
var uciVariant = variantMap[opts.variant.key];
|
|
@ -0,0 +1,125 @@
|
|||
var m = require('mithril');
|
||||
|
||||
module.exports = function(opts, name) {
|
||||
|
||||
var instance = null;
|
||||
var busy = false;
|
||||
var stopping = false;
|
||||
|
||||
// Sunsetter always plays only moves right away. Count the number of played
|
||||
// moves to show the correct mate in #n.
|
||||
var onlyMoves = 0;
|
||||
var best;
|
||||
|
||||
var send = function(text) {
|
||||
instance.postMessage(text);
|
||||
};
|
||||
|
||||
var processOutput = function(text, work) {
|
||||
if (text === 'tellics stopped') {
|
||||
busy = false;
|
||||
stopping = false;
|
||||
onlyMoves = 0;
|
||||
best = undefined;
|
||||
return;
|
||||
}
|
||||
if (stopping) return;
|
||||
|
||||
if (text.indexOf('move ') == 0) {
|
||||
onlyMoves++;
|
||||
best = text.split(' ')[1];
|
||||
send('analyze');
|
||||
return;
|
||||
}
|
||||
|
||||
var depth, cp, mate;
|
||||
|
||||
var matches = text.match(/(\d+)\s+([-+]?\d+)\s+(\d+)\s+(\d+)\s+([a-h1-8=@PNBRQK]+).*/);
|
||||
if (matches) {
|
||||
depth = parseInt(matches[1], 10);
|
||||
cp = parseInt(matches[2], 10);
|
||||
if (!onlyMoves) best = matches[5];
|
||||
} else {
|
||||
matches = text.match(/Found move:\s+([a-h1-8=@PNBRQK]+)\s+([-+]?\d+)\s.*/);
|
||||
if (matches) {
|
||||
depth = opts.maxDepth;
|
||||
cp = parseInt(matches[2], 10);
|
||||
if (!onlyMoves) best = matches[1];
|
||||
stopping = true;
|
||||
send('force');
|
||||
send('tellics stopped');
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!onlyMoves && depth < opts.minDepth) return;
|
||||
|
||||
if ((work.ply + onlyMoves) % 2 == 1) {
|
||||
if (cp) cp = -cp;
|
||||
if (mate) mate = -mate;
|
||||
}
|
||||
|
||||
// transform mate scores
|
||||
if (cp > 20000) {
|
||||
mate = Math.floor((30000 - cp) / 10);
|
||||
cp = undefined;
|
||||
} else if (cp < -20000) {
|
||||
mate = Math.floor((-30000 - cp) / 10);
|
||||
cp = undefined;
|
||||
}
|
||||
|
||||
if (mate) {
|
||||
if (mate > 0) mate += onlyMoves;
|
||||
else mate -= onlyMoves;
|
||||
}
|
||||
|
||||
work.emit({
|
||||
work: work,
|
||||
eval: {
|
||||
depth: depth,
|
||||
cp: cp,
|
||||
mate: mate,
|
||||
best: best
|
||||
},
|
||||
name: name
|
||||
});
|
||||
};
|
||||
|
||||
var reboot = function() {
|
||||
if (instance) instance.terminate();
|
||||
instance = new Worker('/assets/vendor/Sunsetter/sunsetter.js');
|
||||
busy = false;
|
||||
stopping = false;
|
||||
onlyMoves = 0;
|
||||
send('xboard');
|
||||
};
|
||||
|
||||
reboot();
|
||||
|
||||
return {
|
||||
start: function(work) {
|
||||
if (busy) reboot();
|
||||
busy = true;
|
||||
send('variant ' + opts.variant.key);
|
||||
send('setboard ' + work.position);
|
||||
send('force');
|
||||
for (var i = 0; i < work.moves.length; i++) {
|
||||
send(work.moves[i]);
|
||||
}
|
||||
send('analyze');
|
||||
send('go');
|
||||
instance.onmessage = function(msg) {
|
||||
processOutput(msg.data, work);
|
||||
};
|
||||
},
|
||||
stop: function() {
|
||||
if (!busy) return;
|
||||
stopping = true;
|
||||
onlyMoves = 0;
|
||||
best = undefined;
|
||||
send('exit');
|
||||
send('tellics stopped');
|
||||
}
|
||||
};
|
||||
};
|
|
@ -387,7 +387,7 @@ module.exports = function(opts) {
|
|||
});
|
||||
}.bind(this);
|
||||
|
||||
var cevalVariants = ['standard', 'fromPosition', 'chess960', 'kingOfTheHill', 'threeCheck', 'horde', 'racingKings', 'atomic'];
|
||||
var cevalVariants = ['standard', 'fromPosition', 'chess960', 'kingOfTheHill', 'threeCheck', 'horde', 'racingKings', 'atomic', 'crazyhouse'];
|
||||
var cevalPossible = function() {
|
||||
return (util.synthetic(this.data) || !game.playable(this.data)) &&
|
||||
cevalVariants.indexOf(this.data.game.variant.key) !== -1;
|
||||
|
|
Loading…
Reference in New Issue