@datamoc/mw_games 0.20.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/dist/audio/Channels.d.ts +19 -0
  3. package/dist/audio/Channels.d.ts.map +1 -1
  4. package/dist/audio/Channels.js +33 -4
  5. package/dist/audio/Channels.js.map +1 -1
  6. package/dist/audio/LoopTags.d.ts +37 -0
  7. package/dist/audio/LoopTags.d.ts.map +1 -0
  8. package/dist/audio/LoopTags.js +116 -0
  9. package/dist/audio/LoopTags.js.map +1 -0
  10. package/dist/audio/Midi.d.ts +29 -0
  11. package/dist/audio/Midi.d.ts.map +1 -1
  12. package/dist/audio/Midi.js +30 -1
  13. package/dist/audio/Midi.js.map +1 -1
  14. package/dist/audio/MidiRender.d.ts +3 -2
  15. package/dist/audio/MidiRender.d.ts.map +1 -1
  16. package/dist/audio/MidiRender.js +2 -2
  17. package/dist/audio/MidiRender.js.map +1 -1
  18. package/dist/audio/humanize/Groove.d.ts +80 -0
  19. package/dist/audio/humanize/Groove.d.ts.map +1 -0
  20. package/dist/audio/humanize/Groove.js +102 -0
  21. package/dist/audio/humanize/Groove.js.map +1 -0
  22. package/dist/audio/humanize/GrooveConverter.d.ts +49 -0
  23. package/dist/audio/humanize/GrooveConverter.d.ts.map +1 -0
  24. package/dist/audio/humanize/GrooveConverter.js +344 -0
  25. package/dist/audio/humanize/GrooveConverter.js.map +1 -0
  26. package/dist/audio/humanize/GrooveExtractor.d.ts +49 -0
  27. package/dist/audio/humanize/GrooveExtractor.d.ts.map +1 -0
  28. package/dist/audio/humanize/GrooveExtractor.js +179 -0
  29. package/dist/audio/humanize/GrooveExtractor.js.map +1 -0
  30. package/dist/audio/humanize/GrooveHumanizer.d.ts +34 -0
  31. package/dist/audio/humanize/GrooveHumanizer.d.ts.map +1 -0
  32. package/dist/audio/humanize/GrooveHumanizer.js +37 -0
  33. package/dist/audio/humanize/GrooveHumanizer.js.map +1 -0
  34. package/dist/audio/humanize/Humanize.d.ts +54 -0
  35. package/dist/audio/humanize/Humanize.d.ts.map +1 -0
  36. package/dist/audio/humanize/Humanize.js +239 -0
  37. package/dist/audio/humanize/Humanize.js.map +1 -0
  38. package/dist/audio/humanize/HumanizerFactory.d.ts +68 -0
  39. package/dist/audio/humanize/HumanizerFactory.d.ts.map +1 -0
  40. package/dist/audio/humanize/HumanizerFactory.js +84 -0
  41. package/dist/audio/humanize/HumanizerFactory.js.map +1 -0
  42. package/dist/audio/humanize/LiteHumanizer.d.ts +30 -0
  43. package/dist/audio/humanize/LiteHumanizer.d.ts.map +1 -0
  44. package/dist/audio/humanize/LiteHumanizer.js +35 -0
  45. package/dist/audio/humanize/LiteHumanizer.js.map +1 -0
  46. package/dist/audio/humanize/Onsets.d.ts +26 -0
  47. package/dist/audio/humanize/Onsets.d.ts.map +1 -0
  48. package/dist/audio/humanize/Onsets.js +164 -0
  49. package/dist/audio/humanize/Onsets.js.map +1 -0
  50. package/dist/audio/index.d.ts +14 -1
  51. package/dist/audio/index.d.ts.map +1 -1
  52. package/dist/audio/index.js +7 -0
  53. package/dist/audio/index.js.map +1 -1
  54. package/dist/board/bitboard.d.ts +132 -0
  55. package/dist/board/bitboard.d.ts.map +1 -0
  56. package/dist/board/bitboard.js +495 -0
  57. package/dist/board/bitboard.js.map +1 -0
  58. package/dist/board/chess.d.ts +16 -0
  59. package/dist/board/chess.d.ts.map +1 -1
  60. package/dist/board/chess.js +43 -0
  61. package/dist/board/chess.js.map +1 -1
  62. package/dist/board/index.d.ts +9 -1
  63. package/dist/board/index.d.ts.map +1 -1
  64. package/dist/board/index.js +5 -1
  65. package/dist/board/index.js.map +1 -1
  66. package/dist/board/openings.d.ts +58 -0
  67. package/dist/board/openings.d.ts.map +1 -0
  68. package/dist/board/openings.js +45 -0
  69. package/dist/board/openings.js.map +1 -0
  70. package/dist/board/tablebase.d.ts +118 -0
  71. package/dist/board/tablebase.d.ts.map +1 -0
  72. package/dist/board/tablebase.js +414 -0
  73. package/dist/board/tablebase.js.map +1 -0
  74. package/dist/board/tourney.d.ts +90 -0
  75. package/dist/board/tourney.d.ts.map +1 -0
  76. package/dist/board/tourney.js +1013 -0
  77. package/dist/board/tourney.js.map +1 -0
  78. package/dist/core/JavaRandom.d.ts +55 -0
  79. package/dist/core/JavaRandom.d.ts.map +1 -0
  80. package/dist/core/JavaRandom.js +81 -0
  81. package/dist/core/JavaRandom.js.map +1 -0
  82. package/dist/core/index.d.ts +2 -0
  83. package/dist/core/index.d.ts.map +1 -1
  84. package/dist/core/index.js +1 -0
  85. package/dist/core/index.js.map +1 -1
  86. package/dist/mw_games.global.js +123 -116
  87. package/dist/rpg/EventRunner.d.ts +7 -0
  88. package/dist/rpg/EventRunner.d.ts.map +1 -1
  89. package/dist/rpg/EventRunner.js +6 -0
  90. package/dist/rpg/EventRunner.js.map +1 -1
  91. package/dist/rpg/MoveRoute.d.ts +35 -4
  92. package/dist/rpg/MoveRoute.d.ts.map +1 -1
  93. package/dist/rpg/MoveRoute.js +40 -11
  94. package/dist/rpg/MoveRoute.js.map +1 -1
  95. package/dist/two-d/render/FogLayer.d.ts +68 -0
  96. package/dist/two-d/render/FogLayer.d.ts.map +1 -0
  97. package/dist/two-d/render/FogLayer.js +83 -0
  98. package/dist/two-d/render/FogLayer.js.map +1 -0
  99. package/dist/two-d/render/LiquidLayer.d.ts +62 -0
  100. package/dist/two-d/render/LiquidLayer.d.ts.map +1 -0
  101. package/dist/two-d/render/LiquidLayer.js +102 -0
  102. package/dist/two-d/render/LiquidLayer.js.map +1 -0
  103. package/dist/two-d/render/RpgmAutotile.d.ts +42 -0
  104. package/dist/two-d/render/RpgmAutotile.d.ts.map +1 -1
  105. package/dist/two-d/render/RpgmAutotile.js +71 -4
  106. package/dist/two-d/render/RpgmAutotile.js.map +1 -1
  107. package/dist/two-d/render/TileMap.d.ts +50 -2
  108. package/dist/two-d/render/TileMap.d.ts.map +1 -1
  109. package/dist/two-d/render/TileMap.js +120 -2
  110. package/dist/two-d/render/TileMap.js.map +1 -1
  111. package/dist/two-d/render/index.d.ts +7 -3
  112. package/dist/two-d/render/index.d.ts.map +1 -1
  113. package/dist/two-d/render/index.js +3 -1
  114. package/dist/two-d/render/index.js.map +1 -1
  115. package/dist/two-d/ui/Label.d.ts.map +1 -1
  116. package/dist/two-d/ui/Label.js +11 -2
  117. package/dist/two-d/ui/Label.js.map +1 -1
  118. package/dist/two-d/ui/ListView.d.ts +24 -0
  119. package/dist/two-d/ui/ListView.d.ts.map +1 -1
  120. package/dist/two-d/ui/ListView.js +97 -4
  121. package/dist/two-d/ui/ListView.js.map +1 -1
  122. package/dist/two-d/ui/MessageLog.d.ts +62 -0
  123. package/dist/two-d/ui/MessageLog.d.ts.map +1 -0
  124. package/dist/two-d/ui/MessageLog.js +114 -0
  125. package/dist/two-d/ui/MessageLog.js.map +1 -0
  126. package/dist/two-d/ui/RadioGroup.d.ts +68 -0
  127. package/dist/two-d/ui/RadioGroup.d.ts.map +1 -0
  128. package/dist/two-d/ui/RadioGroup.js +177 -0
  129. package/dist/two-d/ui/RadioGroup.js.map +1 -0
  130. package/dist/two-d/ui/TextModel.d.ts +26 -1
  131. package/dist/two-d/ui/TextModel.d.ts.map +1 -1
  132. package/dist/two-d/ui/TextModel.js +56 -7
  133. package/dist/two-d/ui/TextModel.js.map +1 -1
  134. package/dist/two-d/ui/TextSharpness.d.ts +33 -0
  135. package/dist/two-d/ui/TextSharpness.d.ts.map +1 -0
  136. package/dist/two-d/ui/TextSharpness.js +56 -0
  137. package/dist/two-d/ui/TextSharpness.js.map +1 -0
  138. package/dist/two-d/ui/index.d.ts +5 -0
  139. package/dist/two-d/ui/index.d.ts.map +1 -1
  140. package/dist/two-d/ui/index.js +3 -0
  141. package/dist/two-d/ui/index.js.map +1 -1
  142. package/dist/version.d.ts +1 -1
  143. package/dist/version.js +1 -1
  144. package/package.json +19 -7
  145. package/sbom.cdx.json +194 -32
  146. package/tools/build-tablebases.d.mts +22 -0
  147. package/tools/build-tablebases.mjs +549 -0
  148. package/tools/compile-openings.d.mts +20 -0
  149. package/tools/compile-openings.mjs +130 -0
  150. package/tools/play-uci.d.mts +26 -0
  151. package/tools/play-uci.mjs +194 -0
@@ -0,0 +1,414 @@
1
+ const EXTRA_LETTER = { queen: 'Q', rook: 'R', bishop: 'B', knight: 'N' };
2
+ const LETTER_EXTRA = { Q: 'queen', R: 'rook', B: 'bishop', N: 'knight' };
3
+ const KIND_INDEX = { pawn: 0, knight: 1, bishop: 2, rook: 3, queen: 4, king: 5 };
4
+ /**
5
+ * The canonical id for white extras: strongest piece first, so `['bishop',
6
+ * 'queen']` and `['queen', 'bishop']` name the same `KQBK` ending.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { tablebaseId } from '@datamoc/mw_games/board';
11
+ *
12
+ * console.log(tablebaseId(['bishop', 'queen'])); // 'KQBK'
13
+ * ```
14
+ */
15
+ export function tablebaseId(white) {
16
+ const order = { queen: 0, rook: 1, bishop: 2, knight: 3 };
17
+ return `K${white
18
+ .slice()
19
+ .sort((a, b) => order[a] - order[b])
20
+ .map((kind) => EXTRA_LETTER[kind])
21
+ .join('')}K`;
22
+ }
23
+ const BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
24
+ function base64Encode(raw) {
25
+ let out = '';
26
+ for (let i = 0; i < raw.length; i += 3) {
27
+ const a = raw[i];
28
+ const b = i + 1 < raw.length ? raw[i + 1] : 0;
29
+ const c = i + 2 < raw.length ? raw[i + 2] : 0;
30
+ out += BASE64[a >> 2] + BASE64[((a & 3) << 4) | (b >> 4)];
31
+ out += i + 1 < raw.length ? BASE64[((b & 15) << 2) | (c >> 6)] : '=';
32
+ out += i + 2 < raw.length ? BASE64[c & 63] : '=';
33
+ }
34
+ return out;
35
+ }
36
+ function base64Decode(code) {
37
+ if (code.length % 4 !== 0)
38
+ throw new Error('tablebase data is not base64: length is not a multiple of 4');
39
+ const values = new Array(code.length);
40
+ for (let i = 0; i < code.length; i++) {
41
+ if (code[i] === '=') {
42
+ values[i] = -1;
43
+ continue;
44
+ }
45
+ const value = BASE64.indexOf(code[i]);
46
+ if (value === -1)
47
+ throw new Error(`tablebase data is not base64: ${code[i]}`);
48
+ values[i] = value;
49
+ }
50
+ const out = [];
51
+ for (let i = 0; i < values.length; i += 4) {
52
+ const [a, b, c, d] = [values[i], values[i + 1], values[i + 2], values[i + 3]];
53
+ if (a === -1 || b === -1)
54
+ throw new Error('tablebase data is not base64: padding inside a quantum');
55
+ out.push((a << 2) | (b >> 4));
56
+ if (c !== -1)
57
+ out.push(((b & 15) << 4) | (c >> 2));
58
+ if (d !== -1)
59
+ out.push(((c & 3) << 6) | d);
60
+ }
61
+ return new Uint8Array(out);
62
+ }
63
+ /**
64
+ * Canonical Huffman plus base64, the game decodes with this same
65
+ * dependency-free code. Two dictionary schemes were tried first and both lost
66
+ * to the data: run-length encoding collapsed because a solved ending is a fine
67
+ * win/draw/loss mosaic rather than broad regions, and LZ77 barely beat raw
68
+ * size on the 4-piece mosaics while tripping over its own match flags. Huffman
69
+ * matches the actual skew (draws dominate, distances cluster near zero) with a
70
+ * decoder a reader can hold in their head.
71
+ *
72
+ * @example
73
+ * ```ts
74
+ * import { huffDecode, huffEncode } from '@datamoc/mw_games/board';
75
+ *
76
+ * console.log(huffDecode(huffEncode(new Uint8Array([2, 2, 2, 3])))); // Uint8Array([2, 2, 2, 3])
77
+ * ```
78
+ */
79
+ export function huffEncode(raw) {
80
+ const counts = new Array(256).fill(0);
81
+ for (const byte of raw)
82
+ counts[byte]++;
83
+ const symbols = counts.map((count, symbol) => ({ count, symbol })).filter((entry) => entry.count > 0);
84
+ const header = [1, symbols.length];
85
+ if (symbols.length === 0)
86
+ return base64Encode(new Uint8Array([1, 0, 0, 0, 0, 0]));
87
+ if (symbols.length === 1) {
88
+ header.push(symbols[0].symbol, 0);
89
+ const packed = new Uint8Array(header.length + 4);
90
+ packed.set(header, 0);
91
+ packed[header.length] = raw.length & 255;
92
+ packed[header.length + 1] = (raw.length >> 8) & 255;
93
+ packed[header.length + 2] = (raw.length >> 16) & 255;
94
+ packed[header.length + 3] = (raw.length >> 24) & 255;
95
+ return base64Encode(packed);
96
+ }
97
+ const lengths = huffmanLengths(symbols.map((entry) => entry.count));
98
+ const ordered = symbols
99
+ .map((entry, i) => ({ symbol: entry.symbol, length: lengths[i] }))
100
+ .sort((a, b) => a.symbol - b.symbol);
101
+ for (const entry of ordered)
102
+ header.push(entry.symbol);
103
+ for (const entry of ordered)
104
+ header.push(entry.length);
105
+ const codes = canonicalCodes(ordered);
106
+ const table = new Map();
107
+ for (let i = 0; i < ordered.length; i++)
108
+ table.set(ordered[i].symbol, codes[i]);
109
+ let totalBits = 0;
110
+ for (const entry of symbols)
111
+ totalBits += entry.count * table.get(entry.symbol).length;
112
+ const bytes = new Uint8Array(header.length + 4 + Math.ceil(totalBits / 8));
113
+ bytes.set(header, 0);
114
+ bytes[header.length] = raw.length & 255;
115
+ bytes[header.length + 1] = (raw.length >> 8) & 255;
116
+ bytes[header.length + 2] = (raw.length >> 16) & 255;
117
+ bytes[header.length + 3] = (raw.length >> 24) & 255;
118
+ let bit = 0;
119
+ const firstDataByte = header.length + 4;
120
+ for (const byte of raw) {
121
+ const entry = table.get(byte);
122
+ for (let k = entry.length - 1; k >= 0; k--) {
123
+ if ((entry.code >> k) & 1)
124
+ bytes[firstDataByte + (bit >> 3)] |= 1 << (7 - (bit & 7));
125
+ bit++;
126
+ }
127
+ }
128
+ return base64Encode(bytes);
129
+ }
130
+ /** code lengths from symbol counts: repeatedly merge the two smallest */
131
+ function huffmanLengths(counts) {
132
+ const n = counts.length;
133
+ if (n === 0)
134
+ return [];
135
+ const weights = counts.slice();
136
+ const lengths = new Array(n).fill(0);
137
+ const active = counts.map((_, i) => i);
138
+ const mergeOrder = [];
139
+ while (active.length > 1) {
140
+ active.sort((a, b) => weights[a] - weights[b]);
141
+ const a = active.shift();
142
+ const b = active.shift();
143
+ mergeOrder.push([a, b]);
144
+ weights[a] += weights[b];
145
+ weights[b] = -1;
146
+ active.push(a);
147
+ }
148
+ for (let i = mergeOrder.length - 1; i >= 0; i--) {
149
+ const [a, b] = mergeOrder[i];
150
+ lengths[b] = lengths[a] + 1;
151
+ lengths[a]++;
152
+ }
153
+ if (lengths.some((length) => length > 32))
154
+ throw new Error('tablebase Huffman code too deep');
155
+ return lengths;
156
+ }
157
+ /** canonical codes from (symbol, length) sorted by symbol: counted, not stored */
158
+ function canonicalCodes(ordered) {
159
+ const byLength = ordered.slice().sort((a, b) => a.length - b.length || a.symbol - b.symbol);
160
+ let code = 0;
161
+ let lastLength = byLength[0].length;
162
+ const assigned = new Map();
163
+ for (const entry of byLength) {
164
+ code <<= entry.length - lastLength;
165
+ assigned.set(entry.symbol, { code, length: entry.length });
166
+ code++;
167
+ lastLength = entry.length;
168
+ }
169
+ return ordered.map((entry) => assigned.get(entry.symbol));
170
+ }
171
+ /**
172
+ * The inverse of `huffEncode`: throws on malformed input rather than guessing,
173
+ * because a corrupt table must fail the load, never misprobe. The symbol count
174
+ * in the header must match the decoded symbols exactly, so truncation fails
175
+ * here instead of probing short.
176
+ *
177
+ * @example
178
+ * ```ts
179
+ * import { huffDecode, huffEncode } from '@datamoc/mw_games/board';
180
+ *
181
+ * console.log(huffDecode(huffEncode(new Uint8Array([2, 2])))); // Uint8Array([2, 2])
182
+ * ```
183
+ */
184
+ export function huffDecode(code) {
185
+ const bytes = base64Decode(code);
186
+ if (bytes.length < 2)
187
+ throw new Error('tablebase data holds no header');
188
+ if (bytes[0] !== 1)
189
+ throw new Error(`tablebase data version ${bytes[0]} is not 1`);
190
+ const nSymbols = bytes[1];
191
+ if (2 + 2 * nSymbols > bytes.length)
192
+ throw new Error('tablebase data ends inside its header');
193
+ const symbols = [];
194
+ const lengths = [];
195
+ for (let i = 0; i < nSymbols; i++)
196
+ symbols.push(bytes[2 + i]);
197
+ for (let i = 0; i < nSymbols; i++)
198
+ lengths.push(bytes[2 + nSymbols + i]);
199
+ const at = 2 + 2 * nSymbols;
200
+ if (nSymbols === 0) {
201
+ if (at + 4 !== bytes.length)
202
+ throw new Error('tablebase data trails its empty header');
203
+ return new Uint8Array(0);
204
+ }
205
+ if (nSymbols === 1) {
206
+ if (at + 4 !== bytes.length)
207
+ throw new Error('tablebase data trails its single-symbol header');
208
+ const total = bytes[at] | (bytes[at + 1] << 8) | (bytes[at + 2] << 16) | (bytes[at + 3] << 24);
209
+ return new Uint8Array(total).fill(symbols[0]);
210
+ }
211
+ if (at + 4 > bytes.length)
212
+ throw new Error('tablebase data ends before its count');
213
+ const total = bytes[at] | (bytes[at + 1] << 8) | (bytes[at + 2] << 16) | (bytes[at + 3] << 24);
214
+ const ordered = symbols.map((symbol, i) => ({ symbol, length: lengths[i] }));
215
+ const codes = canonicalCodes(ordered);
216
+ const root = {};
217
+ for (let i = 0; i < ordered.length; i++) {
218
+ let node = root;
219
+ for (let k = codes[i].length - 1; k >= 0; k--) {
220
+ const bit = (codes[i].code >> k) & 1;
221
+ if (k === 0) {
222
+ if (bit)
223
+ node.one = { symbol: ordered[i].symbol };
224
+ else
225
+ node.zero = { symbol: ordered[i].symbol };
226
+ }
227
+ else {
228
+ if (bit)
229
+ node.one = node.one ?? {};
230
+ else
231
+ node.zero = node.zero ?? {};
232
+ node = (bit ? node.one : node.zero);
233
+ }
234
+ }
235
+ }
236
+ const out = new Uint8Array(total);
237
+ let produced = 0;
238
+ let bit = 0;
239
+ const firstDataByte = at + 4;
240
+ const totalBits = (bytes.length - firstDataByte) * 8;
241
+ while (produced < total) {
242
+ if (bit >= totalBits)
243
+ throw new Error('tablebase data ends before its count');
244
+ let node = root;
245
+ for (;;) {
246
+ const byte = bytes[firstDataByte + (bit >> 3)];
247
+ const value = (byte >> (7 - (bit & 7))) & 1;
248
+ bit++;
249
+ node = (value ? node.one : node.zero);
250
+ if (!node)
251
+ throw new Error('tablebase data walks off its Huffman tree');
252
+ if (node.symbol !== undefined)
253
+ break;
254
+ }
255
+ out[produced++] = node.symbol;
256
+ }
257
+ for (; bit < totalBits; bit++) {
258
+ const byte = bytes[firstDataByte + (bit >> 3)];
259
+ if ((byte >> (7 - (bit & 7))) & 1)
260
+ throw new Error('tablebase data does not end in zero padding');
261
+ }
262
+ return out;
263
+ }
264
+ function huffDecodeU16(code) {
265
+ const bytes = huffDecode(code);
266
+ if (bytes.length % 2 !== 0)
267
+ throw new Error('tablebase distances are not byte pairs');
268
+ const out = new Uint16Array(bytes.length / 2);
269
+ for (let i = 0; i < out.length; i++)
270
+ out[i] = bytes[2 * i] | (bytes[2 * i + 1] << 8);
271
+ return out;
272
+ }
273
+ /**
274
+ * Loads a checked-in ending file into probeable arrays: validates the id against
275
+ * its extras, the position count against the piece count, and both payloads
276
+ * against the count, so a truncated artifact fails here with its ending named.
277
+ *
278
+ * @example
279
+ * ```ts
280
+ * import { loadTablebaseEnding } from '@datamoc/mw_games/board';
281
+ *
282
+ * const ending = loadTablebaseEnding({ version: 1, id: 'KBK', white: ['bishop'], positions: 2, wdl: 'AgEC', dtm: 'AAQAAQ' });
283
+ * console.log(ending.id); // 'KBK'
284
+ * ```
285
+ */
286
+ export function loadTablebaseEnding(file) {
287
+ if (file.version !== 1)
288
+ throw new Error(`${file.id}: unknown tablebase version ${String(file.version)}`);
289
+ if (file.id !== tablebaseId(file.white))
290
+ throw new Error(`${file.id}: id does not match its extras`);
291
+ for (const kind of file.white) {
292
+ if (!LETTER_EXTRA[EXTRA_LETTER[kind]])
293
+ throw new Error(`${file.id}: not a tablebase piece: ${String(kind)}`);
294
+ }
295
+ const pieces = 2 + file.white.length;
296
+ let positions = 1;
297
+ for (let i = 0; i < pieces; i++)
298
+ positions *= 64;
299
+ positions *= 2;
300
+ if (file.positions !== positions)
301
+ throw new Error(`${file.id}: claims ${file.positions} positions, holds ${positions}`);
302
+ const wdl = huffDecode(file.wdl);
303
+ if (wdl.length !== positions)
304
+ throw new Error(`${file.id}: WDL decodes to ${wdl.length} positions, needs ${positions}`);
305
+ const dtm = huffDecodeU16(file.dtm);
306
+ if (dtm.length !== positions)
307
+ throw new Error(`${file.id}: distances decode to ${dtm.length} positions, need ${positions}`);
308
+ const strength = { queen: 0, rook: 1, bishop: 2, knight: 3 };
309
+ return {
310
+ id: file.id,
311
+ extras: file.white
312
+ .slice()
313
+ .sort((a, b) => strength[a] - strength[b])
314
+ .map((kind) => KIND_INDEX[kind]),
315
+ positions,
316
+ wdl,
317
+ dtm,
318
+ };
319
+ }
320
+ function placedPieces(state) {
321
+ if ('pieces' in state) {
322
+ const out = [];
323
+ for (let i = 0; i < 12; i++) {
324
+ let bb = state.pieces[i];
325
+ while (bb) {
326
+ const single = bb & -bb;
327
+ out.push({ kind: i % 6, side: i < 6 ? 'white' : 'black', square: Math.log2(Number(single)) });
328
+ bb ^= single;
329
+ }
330
+ }
331
+ return out;
332
+ }
333
+ const out = [];
334
+ state.board.forEach((piece, square) => {
335
+ if (piece)
336
+ out.push({ kind: KIND_INDEX[piece.kind], side: piece.side, square });
337
+ });
338
+ return out;
339
+ }
340
+ function castlingRights(state) {
341
+ if ('pieces' in state)
342
+ return state.castling !== 0;
343
+ const rights = state.castling;
344
+ return rights.whiteKingside || rights.whiteQueenside || rights.blackKingside || rights.blackQueenside;
345
+ }
346
+ /**
347
+ * Probes loaded endings for an exact position: its WDL outcome from the side to
348
+ * move's view with the distance, fifty-move-adjudicated against `halfmove` (a win
349
+ * too far to force in time comes back a draw, and likewise a distant loss).
350
+ * Pure and total: anything outside the shipped scope - pawns, rights, black
351
+ * extras, bare kings, an ending the game never loaded - is a miss (`null`).
352
+ *
353
+ * @example
354
+ * ```ts
355
+ * import { probeTablebase, startingChess } from '@datamoc/mw_games/board';
356
+ *
357
+ * console.log(probeTablebase({}, startingChess())); // null - no endings loaded, never an error
358
+ * ```
359
+ */
360
+ export function probeTablebase(loaded, state, halfmove = 0) {
361
+ if (!Number.isInteger(halfmove) || halfmove < 0)
362
+ throw new RangeError('halfmove must be a non-negative integer');
363
+ const pieces = placedPieces(state);
364
+ const whiteKings = pieces.filter((piece) => piece.kind === 5 && piece.side === 'white');
365
+ const blackKings = pieces.filter((piece) => piece.kind === 5 && piece.side === 'black');
366
+ if (whiteKings.length !== 1 || blackKings.length !== 1)
367
+ return null;
368
+ if (pieces.some((piece) => piece.kind === 0))
369
+ return null;
370
+ if (pieces.some((piece) => piece.kind !== 5 && piece.side === 'black'))
371
+ return null;
372
+ if (castlingRights(state))
373
+ return null;
374
+ const extras = pieces
375
+ .filter((piece) => piece.kind !== 5)
376
+ .sort((a, b) => b.kind - a.kind)
377
+ .map((piece) => piece.kind);
378
+ if (!extras.length)
379
+ return null;
380
+ const order = { 4: 'Q', 3: 'R', 2: 'B', 1: 'N' };
381
+ const id = `K${extras.map((kind) => order[kind]).join('')}K`;
382
+ const ending = loaded[id];
383
+ if (!ending)
384
+ return null;
385
+ const whiteKing = pieces.find((piece) => piece.kind === 5 && piece.side === 'white').square;
386
+ const blackKing = pieces.find((piece) => piece.kind === 5 && piece.side === 'black').square;
387
+ const extraSquares = extras.map((kind, i) => {
388
+ const candidates = pieces.filter((piece) => piece.kind === kind && piece.side === 'white').map((p) => p.square);
389
+ return candidates.sort((a, b) => a - b)[countBefore(extras, kind, i)];
390
+ });
391
+ let index = whiteKing;
392
+ for (const square of extraSquares)
393
+ index = index * 64 + square;
394
+ index = index * 64 + blackKing;
395
+ index = index * 2 + (state.turn === 'black' ? 1 : 0);
396
+ const value = ending.wdl[index];
397
+ if (value === 0)
398
+ return null;
399
+ const dtm = ending.dtm[index];
400
+ let outcome = value === 3 ? 'win' : value === 1 ? 'loss' : 'draw';
401
+ if (outcome !== 'draw' && dtm > 100 - halfmove)
402
+ outcome = 'draw';
403
+ return { outcome, dtm };
404
+ }
405
+ /** which same-kind extra this is: the nth occurrence takes the nth square */
406
+ function countBefore(extras, kind, upto) {
407
+ let seen = 0;
408
+ for (let i = 0; i < upto; i++) {
409
+ if (extras[i] === kind)
410
+ seen++;
411
+ }
412
+ return seen;
413
+ }
414
+ //# sourceMappingURL=tablebase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tablebase.js","sourceRoot":"","sources":["../../src/board/tablebase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ import type { BitboardMove, BitboardState } from './bitboard.ts';
2
+ import type { ChessState } from './chess.ts';
3
+ export interface TourneyOptions {
4
+ /** plies to search; the iterative deepener completes 1..depth while the budget lasts */
5
+ depth?: number;
6
+ /** hard cap on visited positions; the best completed iteration is returned past it */
7
+ maxNodes?: number;
8
+ /** soft wall-clock budget in milliseconds; checked every few thousand nodes */
9
+ timeMs?: number;
10
+ /** aborting stops the search at the next check and keeps the best completed iteration */
11
+ signal?: AbortSignal;
12
+ }
13
+ export interface TourneyAsyncOptions extends TourneyOptions {
14
+ /** root moves searched at once (default: hardware threads capped at 8, else 4) */
15
+ jobs?: number;
16
+ }
17
+ export interface TourneyResult {
18
+ /** the move to play, null only with no legal moves */
19
+ move: BitboardMove | null;
20
+ /** centipawns from the side to move's view; mate scores near 100000, adjusted by distance */
21
+ score: number;
22
+ /** positions visited, quiescence included */
23
+ nodes: number;
24
+ /** the deepest fully completed iteration */
25
+ depth: number;
26
+ }
27
+ /**
28
+ * The tournament engine's serializable task: a full iterative-deepening search over a
29
+ * bitboard position, with nothing outside its own body.
30
+ *
31
+ * `threads.spawn` rehydrates this function in a worker with `new Function`, so it may
32
+ * not reference imports, module scope, or any outer binding: every rule it touches is
33
+ * nested inside it. The main-thread wrappers call this same function directly, so the
34
+ * two sides cannot diverge the way a copied worker body could.
35
+ *
36
+ * What it does, per Roadmap item 390 phase 1: negamax alpha-beta with principal
37
+ * variation search, null-move pruning, late-move reductions, iterative deepening with
38
+ * aspiration windows, a bounded transposition table over Zobrist keys, quiescence over
39
+ * captures and promotions, ordering by hash move then MVV-LVA captures then killers
40
+ * then history, and a classical material plus in-house piece-square evaluation.
41
+ * Positions are plain bitboard data, so they structured-clone into a worker untouched.
42
+ *
43
+ * Draws: stalemate, fifty moves, KvK/KBvK/KNvK dead material, and repetition along the
44
+ * search path all score 0. Repetition only sees the path from the searched position,
45
+ * not the game before it; mate scores prefer the faster mate.
46
+ */
47
+ export declare function tourneyThink(position: BitboardState, options?: {
48
+ depth?: number;
49
+ maxNodes?: number;
50
+ timeMs?: number;
51
+ signal?: AbortSignal;
52
+ }): TourneyResult;
53
+ /**
54
+ * Chooses a move with the tournament search: the same `tourneyThink` task the
55
+ * workers run, called directly, so one implementation serves both sides.
56
+ *
57
+ * This is the stronger engine beside `board/Engine`'s small deterministic one: the
58
+ * minigame path keeps the small search and never pays for this module. Scores are
59
+ * centipawns from the side to move's view; mate scores sit near 100000, adjusted so
60
+ * the faster mate scores higher.
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * import { searchTourney, startingBitboard, tourneyThink } from '@datamoc/mw_games/board';
65
+ *
66
+ * const direct = tourneyThink(startingBitboard(), { depth: 1 });
67
+ * const result = searchTourney(startingBitboard(), { depth: 2 });
68
+ * console.log(direct.move !== null && result.move !== null); // true - the opening position always has legal moves
69
+ * ```
70
+ */
71
+ export declare function searchTourney(state: ChessState | BitboardState, options?: TourneyOptions): TourneyResult;
72
+ /**
73
+ * Chooses a move the way `searchTourney` does, but thinks on worker threads through
74
+ * `threads.spawn`, so a deep search does not drop the caller's frames. Each root move
75
+ * is a self-contained `tourneyThink` task over a structured-cloned bitboard, scored
76
+ * concurrently down a capped lane queue; the best child score from the opponent's
77
+ * view is the worst for us, so the root plays the move whose child scored lowest,
78
+ * with ties going to the earlier root move. An aborting signal rejects through
79
+ * `threads.spawn` and terminates the workers.
80
+ *
81
+ * @example
82
+ * ```ts
83
+ * import { searchTourneyAsync, startingBitboard } from '@datamoc/mw_games/board';
84
+ *
85
+ * const result = await searchTourneyAsync(startingBitboard(), { depth: 2 });
86
+ * console.log(result.move !== null); // true - the opening position always has legal moves
87
+ * ```
88
+ */
89
+ export declare function searchTourneyAsync(state: ChessState | BitboardState, options?: TourneyAsyncOptions): Promise<TourneyResult>;
90
+ //# sourceMappingURL=tourney.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tourney.d.ts","sourceRoot":"","sources":["../../src/board/tourney.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACjE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,MAAM,WAAW,cAAc;IAC9B,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yFAAyF;IACzF,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,mBAAoB,SAAQ,cAAc;IAC1D,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC7B,sDAAsD;IACtD,IAAI,EAAE,YAAY,GAAG,IAAI,CAAC;IAC1B,6FAA6F;IAC7F,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC3B,QAAQ,EAAE,aAAa,EACvB,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GACxF,aAAa,CAo0Bf;AAcD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,UAAU,GAAG,aAAa,EAAE,OAAO,GAAE,cAAmB,GAAG,aAAa,CAO5G;AAuBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,kBAAkB,CACvC,KAAK,EAAE,UAAU,GAAG,aAAa,EACjC,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,aAAa,CAAC,CA+CxB"}