87 lines
2.1 KiB
JavaScript
87 lines
2.1 KiB
JavaScript
var m = require('mithril');
|
|
|
|
var variantMap = {
|
|
fromPosition: 'Chess960',
|
|
chess960: 'Chess960',
|
|
atomic: 'Atomic',
|
|
horde: 'Horde',
|
|
crazyhouse: 'House',
|
|
kingOfTheHill: 'KingOfTheHill',
|
|
racingKings: 'Race',
|
|
threeCheck: '3Check',
|
|
antichess: 'Anti'
|
|
};
|
|
|
|
module.exports = function(opts, name) {
|
|
|
|
var instance = null;
|
|
var busy = false;
|
|
var stopping = false;
|
|
|
|
var send = function(text) {
|
|
instance.postMessage(text);
|
|
};
|
|
|
|
var processOutput = function(text, work) {
|
|
if (text.indexOf('bestmove ') === 0) {
|
|
busy = false;
|
|
stopping = false;
|
|
return;
|
|
}
|
|
if (stopping) return;
|
|
if (/currmovenumber|lowerbound|upperbound/.test(text)) return;
|
|
var matches = text.match(/depth (\d+) .*score (cp|mate) ([-\d]+) .*nps (\d+) .*pv (.+)/);
|
|
if (!matches) return;
|
|
var depth = parseInt(matches[1]);
|
|
if (depth < opts.minDepth) return;
|
|
var cp, mate;
|
|
if (matches[2] === 'cp') cp = parseFloat(matches[3]);
|
|
else mate = parseFloat(matches[3]);
|
|
if (work.ply % 2 === 1) {
|
|
if (matches[2] === 'cp') cp = -cp;
|
|
else mate = -mate;
|
|
}
|
|
var best = matches[5].split(' ')[0];
|
|
work.emit({
|
|
work: work,
|
|
eval: {
|
|
depth: depth,
|
|
cp: cp,
|
|
mate: mate,
|
|
best: best,
|
|
nps: parseInt(matches[4])
|
|
},
|
|
name: name
|
|
});
|
|
};
|
|
|
|
var reboot = function() {
|
|
if (instance) instance.terminate();
|
|
instance = new Worker('/assets/vendor/stockfish.js/stockfish.js');
|
|
busy = false;
|
|
stopping = false;
|
|
var uciVariant = variantMap[opts.variant.key];
|
|
if (uciVariant) send('setoption name UCI_' + uciVariant + ' value true');
|
|
else send('uci'); // send something to warm up
|
|
};
|
|
|
|
reboot();
|
|
|
|
return {
|
|
start: function(work) {
|
|
if (busy) reboot();
|
|
busy = true;
|
|
send(['position', 'fen', work.initialFen, 'moves'].concat(work.moves).join(' '));
|
|
send('go depth ' + work.maxDepth);
|
|
instance.onmessage = function(msg) {
|
|
processOutput(msg.data, work);
|
|
};
|
|
},
|
|
stop: function() {
|
|
if (!busy) return;
|
|
stopping = true;
|
|
send('stop');
|
|
}
|
|
};
|
|
};
|