-
-
Notifications
You must be signed in to change notification settings - Fork 2.2k
/
sunsetterWorker.js
120 lines (106 loc) · 2.81 KB
/
sunsetterWorker.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
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.
// When aiMoves is > 0 Sunsetter is in analysis mode, which uses an absolute
// eval score instead of relative to current color.
var aiMoves = 0;
var best;
var send = function(text) {
instance.postMessage(text);
};
var processOutput = function(text, work) {
if (text === 'tellics stopped') {
busy = false;
stopping = false;
aiMoves = 0;
best = undefined;
return;
}
if (stopping) return;
if (text.indexOf('move ') == 0) {
aiMoves++;
best = text.split(' ')[1];
if (!stopping) 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 (!aiMoves) {
best = matches[5];
if (depth < opts.minDepth) return;
}
} else {
matches = text.match(/Found move:\s+([a-h1-8=@PNBRQK]+)\s+([-+]?\d+)\s.*/);
if (matches) {
cp = parseInt(matches[2], 10);
if (!aiMoves) best = matches[1];
if (!stopping) send('analyze');
} else {
return;
}
}
if (cp && !aiMoves && work.ply % 2) {
cp = -cp;
}
// transform mate scores
if (Math.abs(cp) > 20000) {
mate = Math.floor((30000 - Math.abs(cp)) / 10) + 1;
// approx depth for searches that end early with mate
depth = Math.max(depth || 0, mate * 2 - 1);
// correct sign and add sunsetter played moves
mate = Math.sign(cp) * (mate + aiMoves);
cp = undefined;
}
work.emit({
work: work,
eval: {
depth: depth + aiMoves,
cp: cp,
mate: mate,
best: best
},
name: name
});
};
var reboot = function() {
if (instance) instance.terminate();
instance = new Worker('/assets/vendor/Sunsetter8/sunsetter.js');
busy = false;
stopping = false;
aiMoves = 0;
send('xboard');
};
reboot();
return {
start: function(work) {
if (busy) reboot();
busy = true;
send('reset ' + opts.variant.key);
send('setboard ' + work.initialFen);
send('easy');
send('force');
for (var i = 0; i < work.moves.length; i++) {
send(work.moves[i]);
}
send('go');
instance.onmessage = function(msg) {
processOutput(msg.data, work);
};
},
stop: function() {
if (!busy) return;
stopping = true;
aiMoves = 0;
best = undefined;
send('exit');
send('tellics stopped');
}
};
};