@fnndsc/brasa 0.31.5 → 0.32.1

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 (66) hide show
  1. package/dist/buildinfo.json +1 -1
  2. package/dist/builtins/games/bytes.d.ts +21 -0
  3. package/dist/builtins/games/bytes.js +224 -0
  4. package/dist/builtins/games/bytes.js.map +1 -0
  5. package/dist/builtins/games/chimes.d.ts +64 -0
  6. package/dist/builtins/games/chimes.js +223 -0
  7. package/dist/builtins/games/chimes.js.map +1 -0
  8. package/dist/builtins/games/cowsay.d.ts +36 -0
  9. package/dist/builtins/games/cowsay.js +127 -0
  10. package/dist/builtins/games/cowsay.js.map +1 -0
  11. package/dist/builtins/games/figlet.d.ts +25 -0
  12. package/dist/builtins/games/figlet.js +109 -0
  13. package/dist/builtins/games/figlet.js.map +1 -0
  14. package/dist/builtins/games/lab.d.ts +51 -0
  15. package/dist/builtins/games/lab.js +161 -0
  16. package/dist/builtins/games/lab.js.map +1 -0
  17. package/dist/builtins/games/lolcat.d.ts +26 -0
  18. package/dist/builtins/games/lolcat.js +71 -0
  19. package/dist/builtins/games/lolcat.js.map +1 -0
  20. package/dist/builtins/games/morse.d.ts +18 -0
  21. package/dist/builtins/games/morse.js +46 -0
  22. package/dist/builtins/games/morse.js.map +1 -0
  23. package/dist/builtins/games/numbers.d.ts +55 -0
  24. package/dist/builtins/games/numbers.js +270 -0
  25. package/dist/builtins/games/numbers.js.map +1 -0
  26. package/dist/builtins/games/play.d.ts +53 -0
  27. package/dist/builtins/games/play.js +228 -0
  28. package/dist/builtins/games/play.js.map +1 -0
  29. package/dist/builtins/games/qr.d.ts +40 -0
  30. package/dist/builtins/games/qr.js +336 -0
  31. package/dist/builtins/games/qr.js.map +1 -0
  32. package/dist/builtins/games/shelf.d.ts +27 -0
  33. package/dist/builtins/games/shelf.js +71 -0
  34. package/dist/builtins/games/shelf.js.map +1 -0
  35. package/dist/builtins/games/show.d.ts +38 -0
  36. package/dist/builtins/games/show.js +75 -0
  37. package/dist/builtins/games/show.js.map +1 -0
  38. package/dist/builtins/games/sky.d.ts +69 -0
  39. package/dist/builtins/games/sky.js +190 -0
  40. package/dist/builtins/games/sky.js.map +1 -0
  41. package/dist/builtins/games/stdin.d.ts +34 -0
  42. package/dist/builtins/games/stdin.js +48 -0
  43. package/dist/builtins/games/stdin.js.map +1 -0
  44. package/dist/builtins/games/text.d.ts +46 -0
  45. package/dist/builtins/games/text.js +133 -0
  46. package/dist/builtins/games/text.js.map +1 -0
  47. package/dist/builtins/games/wtf.d.ts +13 -0
  48. package/dist/builtins/games/wtf.data.d.ts +12 -0
  49. package/dist/builtins/games/wtf.data.js +70 -0
  50. package/dist/builtins/games/wtf.data.js.map +1 -0
  51. package/dist/builtins/games/wtf.js +45 -0
  52. package/dist/builtins/games/wtf.js.map +1 -0
  53. package/dist/builtins/help.d.ts +8 -0
  54. package/dist/builtins/help.js +303 -1
  55. package/dist/builtins/help.js.map +1 -1
  56. package/dist/core/dispatch.js +125 -9
  57. package/dist/core/dispatch.js.map +1 -1
  58. package/dist/core/engine.js +1 -0
  59. package/dist/core/engine.js.map +1 -1
  60. package/dist/core/surface.d.ts +14 -0
  61. package/dist/core/surface.js.map +1 -1
  62. package/dist/lib/vfs/providers/static.js +15 -1
  63. package/dist/lib/vfs/providers/static.js.map +1 -1
  64. package/dist/lib/vfs/providers/static_content.js +2 -2
  65. package/dist/lib/vfs/providers/static_content.js.map +1 -1
  66. package/package.json +1 -1
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @file `morse`: text to code and back.
3
+ *
4
+ * `morse hello` taps it out; `morse -d .... . .-.. .-.. ---` reads it. One
5
+ * space between letters, a slash between words, as operators write it. The
6
+ * typed model carries the code so a surface with a speaker can sound it.
7
+ *
8
+ * @module
9
+ */
10
+ import { CommandEnvelope } from '@fnndsc/cumin';
11
+ /** The International code. */
12
+ export declare const MORSE: Readonly<Record<string, string>>;
13
+ /** Text to code: letters a space apart, words a slash apart; an unknown character is dropped. */
14
+ export declare function morse_encode(text: string): string;
15
+ /** Code to text: a group the code does not know becomes `?`. */
16
+ export declare function morse_decode(code: string): string;
17
+ /** `morse [-d] [text]` */
18
+ export declare function builtin_morse(args: string[]): Promise<CommandEnvelope>;
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @file `morse`: text to code and back.
3
+ *
4
+ * `morse hello` taps it out; `morse -d .... . .-.. .-.. ---` reads it. One
5
+ * space between letters, a slash between words, as operators write it. The
6
+ * typed model carries the code so a surface with a speaker can sound it.
7
+ *
8
+ * @module
9
+ */
10
+ import { envelope_ok, envelope_error } from '@fnndsc/cumin';
11
+ import { text_input } from './stdin.js';
12
+ /** The International code. */
13
+ export const MORSE = {
14
+ A: '.-', B: '-...', C: '-.-.', D: '-..', E: '.', F: '..-.', G: '--.', H: '....', I: '..', J: '.---',
15
+ K: '-.-', L: '.-..', M: '--', N: '-.', O: '---', P: '.--.', Q: '--.-', R: '.-.', S: '...', T: '-',
16
+ U: '..-', V: '...-', W: '.--', X: '-..-', Y: '-.--', Z: '--..',
17
+ '0': '-----', '1': '.----', '2': '..---', '3': '...--', '4': '....-', '5': '.....', '6': '-....', '7': '--...', '8': '---..', '9': '----.',
18
+ '.': '.-.-.-', ',': '--..--', '?': '..--..', '!': '-.-.--', '/': '-..-.', '(': '-.--.', ')': '-.--.-', '&': '.-...', ':': '---...',
19
+ ';': '-.-.-.', '=': '-...-', '+': '.-.-.', '-': '-....-', '_': '..--.-', '"': '.-..-.', '$': '...-..-', '@': '.--.-.', '\'': '.----.',
20
+ };
21
+ const MORSE_BACK = Object.fromEntries(Object.entries(MORSE).map(([letter, code]) => [code, letter]));
22
+ /** Text to code: letters a space apart, words a slash apart; an unknown character is dropped. */
23
+ export function morse_encode(text) {
24
+ return text.toUpperCase().trim().split(/\s+/).map((word) => [...word].map((c) => MORSE[c] ?? '').filter((c) => c.length > 0).join(' ')).filter((w) => w.length > 0).join(' / ');
25
+ }
26
+ /** Code to text: a group the code does not know becomes `?`. */
27
+ export function morse_decode(code) {
28
+ return code.trim().split(/\s*\/\s*|\s{3,}/).map((word) => word.trim().split(/\s+/).filter((g) => g.length > 0).map((g) => MORSE_BACK[g] ?? '?').join('')).join(' ');
29
+ }
30
+ /** `morse [-d] [text]` */
31
+ export async function builtin_morse(args) {
32
+ const decode = args[0] === '-d' || args[0] === '--decode';
33
+ const text = text_input(decode ? args.slice(1) : args);
34
+ if (text === null)
35
+ return envelope_error('', undefined, 'morse: usage: morse <text> | morse -d <code>\n');
36
+ const said = text.replace(/\n$/, '');
37
+ if (decode) {
38
+ const plain = morse_decode(said);
39
+ return envelope_ok(`${plain}\n`, { kind: 'games.morse', data: { text: plain, code: said.trim(), direction: 'decode' } });
40
+ }
41
+ const code = morse_encode(said);
42
+ if (code === '')
43
+ return envelope_error('', undefined, 'morse: nothing in that the code can carry\n');
44
+ return envelope_ok(`${code}\n`, { kind: 'games.morse', data: { text: said, code, direction: 'encode' } });
45
+ }
46
+ //# sourceMappingURL=morse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"morse.js","sourceRoot":"","sources":["../../../src/builtins/games/morse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @file Number toys from the shelf: `factor`, `primes`, `roll`, `calc`, `units`.
3
+ *
4
+ * `calc` is a small arithmetic reader of its own — no `eval` — with the
5
+ * usual operators, parentheses, a few functions and `pi` and `e`. `units`
6
+ * converts within a modest table: length, mass, time, data and temperature.
7
+ *
8
+ * @module
9
+ */
10
+ import { CommandEnvelope } from '@fnndsc/cumin';
11
+ /** The most primes `primes` lists in one call. */
12
+ export declare const PRIMES_MAX: number;
13
+ /** The prime factors of n, smallest first, with repeats. */
14
+ export declare function factors_of(n: number): number[];
15
+ /** The primes in [from, to], at most PRIMES_MAX of them. */
16
+ export declare function primes_between(from: number, to: number): number[];
17
+ /**
18
+ * Rolls dice written as `NdS[+M]`, e.g. `2d6+1`, `d20`.
19
+ *
20
+ * @returns Each die's face and the total, or a refusal.
21
+ */
22
+ export declare function dice_roll(spec: string, random?: () => number): {
23
+ rolls: number[];
24
+ modifier: number;
25
+ total: number;
26
+ } | {
27
+ refusal: string;
28
+ };
29
+ /**
30
+ * Evaluates an arithmetic expression: + - * / % ^, parentheses, unary minus,
31
+ * the functions above, pi and e. Throws with a reason on a malformed one.
32
+ */
33
+ export declare function calc_evaluate(expression: string): number;
34
+ /**
35
+ * Converts a quantity between two units of one kind.
36
+ *
37
+ * @returns The converted value, or a refusal naming what went wrong.
38
+ */
39
+ export declare function units_convert(value: number, from: string, to: string): {
40
+ value: number;
41
+ } | {
42
+ refusal: string;
43
+ };
44
+ /** The unit names `units` knows, for its help and its refusals. */
45
+ export declare function units_known(): string[];
46
+ /** `factor N...` */
47
+ export declare function builtin_factor(args: string[]): Promise<CommandEnvelope>;
48
+ /** `primes [FROM] TO` */
49
+ export declare function builtin_primes(args: string[]): Promise<CommandEnvelope>;
50
+ /** `roll [NdS[+M]]...` — 1d6 when bare. */
51
+ export declare function builtin_roll(args: string[]): Promise<CommandEnvelope>;
52
+ /** `calc EXPRESSION` */
53
+ export declare function builtin_calc(args: string[]): Promise<CommandEnvelope>;
54
+ /** `units VALUE FROM [to] TO` */
55
+ export declare function builtin_units(args: string[]): Promise<CommandEnvelope>;
@@ -0,0 +1,270 @@
1
+ /**
2
+ * @file Number toys from the shelf: `factor`, `primes`, `roll`, `calc`, `units`.
3
+ *
4
+ * `calc` is a small arithmetic reader of its own — no `eval` — with the
5
+ * usual operators, parentheses, a few functions and `pi` and `e`. `units`
6
+ * converts within a modest table: length, mass, time, data and temperature.
7
+ *
8
+ * @module
9
+ */
10
+ import { envelope_ok, envelope_error } from '@fnndsc/cumin';
11
+ import { text_input } from './stdin.js';
12
+ /** The most primes `primes` lists in one call. */
13
+ export const PRIMES_MAX = 10_000;
14
+ /** The prime factors of n, smallest first, with repeats. */
15
+ export function factors_of(n) {
16
+ const out = [];
17
+ let rest = n;
18
+ for (let p = 2; p * p <= rest; p++) {
19
+ while (rest % p === 0) {
20
+ out.push(p);
21
+ rest /= p;
22
+ }
23
+ }
24
+ if (rest > 1)
25
+ out.push(rest);
26
+ return out;
27
+ }
28
+ /** The primes in [from, to], at most PRIMES_MAX of them. */
29
+ export function primes_between(from, to) {
30
+ const out = [];
31
+ const isPrime = (n) => {
32
+ if (n < 2)
33
+ return false;
34
+ for (let p = 2; p * p <= n; p++)
35
+ if (n % p === 0)
36
+ return false;
37
+ return true;
38
+ };
39
+ for (let n = Math.max(2, from); n <= to && out.length < PRIMES_MAX; n++)
40
+ if (isPrime(n))
41
+ out.push(n);
42
+ return out;
43
+ }
44
+ /**
45
+ * Rolls dice written as `NdS[+M]`, e.g. `2d6+1`, `d20`.
46
+ *
47
+ * @returns Each die's face and the total, or a refusal.
48
+ */
49
+ export function dice_roll(spec, random = Math.random) {
50
+ const m = /^(\d*)d(\d+)([+-]\d+)?$/i.exec(spec.trim());
51
+ if (m === null)
52
+ return { refusal: `roll: '${spec}' is not dice (try 2d6, d20, 3d8+2)` };
53
+ const count = m[1] === '' || m[1] === undefined ? 1 : Number(m[1]);
54
+ const sides = Number(m[2]);
55
+ const modifier = m[3] === undefined ? 0 : Number(m[3]);
56
+ if (count < 1 || count > 100 || sides < 2 || sides > 1000)
57
+ return { refusal: 'roll: 1 to 100 dice of 2 to 1000 sides' };
58
+ const rolls = Array.from({ length: count }, () => 1 + Math.floor(random() * sides));
59
+ return { rolls, modifier, total: rolls.reduce((a, b) => a + b, 0) + modifier };
60
+ }
61
+ /* ------------------------------------------------------------- calc */
62
+ const CALC_FUNCTIONS = {
63
+ sqrt: Math.sqrt, abs: Math.abs, ln: Math.log, log: Math.log10, log2: Math.log2, exp: Math.exp,
64
+ sin: Math.sin, cos: Math.cos, tan: Math.tan, asin: Math.asin, acos: Math.acos, atan: Math.atan,
65
+ floor: Math.floor, ceil: Math.ceil, round: Math.round,
66
+ };
67
+ const CALC_CONSTANTS = { pi: Math.PI, e: Math.E, tau: 2 * Math.PI };
68
+ /**
69
+ * Evaluates an arithmetic expression: + - * / % ^, parentheses, unary minus,
70
+ * the functions above, pi and e. Throws with a reason on a malformed one.
71
+ */
72
+ export function calc_evaluate(expression) {
73
+ const src = expression.replace(/\s+/g, '');
74
+ let at = 0;
75
+ const peek = () => src[at] ?? '';
76
+ const fail = (why) => { throw new Error(`calc: ${why} at position ${at + 1}`); };
77
+ const number = () => {
78
+ const m = /^(\d+\.?\d*|\.\d+)(e[+-]?\d+)?/i.exec(src.slice(at));
79
+ if (m === null)
80
+ return fail('expected a number');
81
+ at += m[0].length;
82
+ return Number(m[0]);
83
+ };
84
+ const atom = () => {
85
+ if (peek() === '(') {
86
+ at++;
87
+ const v = expr();
88
+ if (peek() !== ')')
89
+ return fail("expected ')'");
90
+ at++;
91
+ return v;
92
+ }
93
+ if (peek() === '-') {
94
+ at++;
95
+ return -atom();
96
+ }
97
+ if (peek() === '+') {
98
+ at++;
99
+ return atom();
100
+ }
101
+ const word = /^[a-z][a-z0-9]*/i.exec(src.slice(at));
102
+ if (word !== null) {
103
+ const name = word[0].toLowerCase();
104
+ at += name.length;
105
+ if (name in CALC_CONSTANTS)
106
+ return CALC_CONSTANTS[name];
107
+ const fn = CALC_FUNCTIONS[name];
108
+ if (fn === undefined)
109
+ return fail(`unknown name '${name}'`);
110
+ if (peek() !== '(')
111
+ return fail(`'${name}' wants parentheses`);
112
+ at++;
113
+ const v = expr();
114
+ if (peek() !== ')')
115
+ return fail("expected ')'");
116
+ at++;
117
+ return fn(v);
118
+ }
119
+ return number();
120
+ };
121
+ const power = () => {
122
+ const base = atom();
123
+ if (peek() === '^') {
124
+ at++;
125
+ return Math.pow(base, power());
126
+ }
127
+ return base;
128
+ };
129
+ const term = () => {
130
+ let v = power();
131
+ while (peek() === '*' || peek() === '/' || peek() === '%') {
132
+ const op = peek();
133
+ at++;
134
+ const r = power();
135
+ v = op === '*' ? v * r : op === '/' ? v / r : v % r;
136
+ }
137
+ return v;
138
+ };
139
+ const expr = () => {
140
+ let v = term();
141
+ while (peek() === '+' || peek() === '-') {
142
+ const op = peek();
143
+ at++;
144
+ const r = term();
145
+ v = op === '+' ? v + r : v - r;
146
+ }
147
+ return v;
148
+ };
149
+ if (src === '')
150
+ fail('nothing to compute');
151
+ const value = expr();
152
+ if (at < src.length)
153
+ fail(`unexpected '${peek()}'`);
154
+ return value;
155
+ }
156
+ const UNITS = {
157
+ m: { kind: 'length', factor: 1 }, meter: { kind: 'length', factor: 1 }, metre: { kind: 'length', factor: 1 },
158
+ km: { kind: 'length', factor: 1000 }, cm: { kind: 'length', factor: 0.01 }, mm: { kind: 'length', factor: 0.001 }, um: { kind: 'length', factor: 1e-6 },
159
+ in: { kind: 'length', factor: 0.0254 }, inch: { kind: 'length', factor: 0.0254 }, ft: { kind: 'length', factor: 0.3048 }, foot: { kind: 'length', factor: 0.3048 }, feet: { kind: 'length', factor: 0.3048 },
160
+ yd: { kind: 'length', factor: 0.9144 }, mi: { kind: 'length', factor: 1609.344 }, mile: { kind: 'length', factor: 1609.344 }, nmi: { kind: 'length', factor: 1852 },
161
+ kg: { kind: 'mass', factor: 1 }, g: { kind: 'mass', factor: 0.001 }, mg: { kind: 'mass', factor: 1e-6 }, lb: { kind: 'mass', factor: 0.45359237 }, oz: { kind: 'mass', factor: 0.028349523125 }, st: { kind: 'mass', factor: 6.35029318 },
162
+ s: { kind: 'time', factor: 1 }, sec: { kind: 'time', factor: 1 }, ms: { kind: 'time', factor: 0.001 }, us: { kind: 'time', factor: 1e-6 }, min: { kind: 'time', factor: 60 }, h: { kind: 'time', factor: 3600 }, hr: { kind: 'time', factor: 3600 },
163
+ d: { kind: 'time', factor: 86400 }, day: { kind: 'time', factor: 86400 }, wk: { kind: 'time', factor: 604800 }, week: { kind: 'time', factor: 604800 }, yr: { kind: 'time', factor: 31557600 }, year: { kind: 'time', factor: 31557600 },
164
+ B: { kind: 'data', factor: 1 }, byte: { kind: 'data', factor: 1 }, kB: { kind: 'data', factor: 1e3 }, MB: { kind: 'data', factor: 1e6 }, GB: { kind: 'data', factor: 1e9 }, TB: { kind: 'data', factor: 1e12 },
165
+ KiB: { kind: 'data', factor: 1024 }, MiB: { kind: 'data', factor: 1024 ** 2 }, GiB: { kind: 'data', factor: 1024 ** 3 }, TiB: { kind: 'data', factor: 1024 ** 4 }, bit: { kind: 'data', factor: 0.125 },
166
+ C: { kind: 'temperature', factor: 1 }, F: { kind: 'temperature', factor: 1 }, K: { kind: 'temperature', factor: 1 },
167
+ };
168
+ /** Temperature is affine, not a factor: converted by hand. */
169
+ function temperature_convert(value, from, to) {
170
+ const celsius = from === 'C' ? value : from === 'F' ? (value - 32) * 5 / 9 : value - 273.15;
171
+ return to === 'C' ? celsius : to === 'F' ? celsius * 9 / 5 + 32 : celsius + 273.15;
172
+ }
173
+ /**
174
+ * Converts a quantity between two units of one kind.
175
+ *
176
+ * @returns The converted value, or a refusal naming what went wrong.
177
+ */
178
+ export function units_convert(value, from, to) {
179
+ const a = UNITS[from] ?? UNITS[from.toLowerCase()];
180
+ const b = UNITS[to] ?? UNITS[to.toLowerCase()];
181
+ if (a === undefined)
182
+ return { refusal: `units: unknown unit '${from}'` };
183
+ if (b === undefined)
184
+ return { refusal: `units: unknown unit '${to}'` };
185
+ if (a.kind !== b.kind)
186
+ return { refusal: `units: cannot convert ${a.kind} to ${b.kind}` };
187
+ if (a.kind === 'temperature')
188
+ return { value: temperature_convert(value, from.toUpperCase(), to.toUpperCase()) };
189
+ return { value: value * a.factor / b.factor };
190
+ }
191
+ /** The unit names `units` knows, for its help and its refusals. */
192
+ export function units_known() {
193
+ return Object.keys(UNITS);
194
+ }
195
+ /* --------------------------------------------------------- builtins */
196
+ /** `factor N...` */
197
+ export async function builtin_factor(args) {
198
+ const words = text_input(args)?.trim().split(/\s+/) ?? [];
199
+ if (words.length === 0)
200
+ return envelope_error('', undefined, 'factor: usage: factor N [N...]\n');
201
+ const lines = [];
202
+ const data = [];
203
+ for (const word of words) {
204
+ const n = Number(word);
205
+ if (!Number.isInteger(n) || n < 1 || n > Number.MAX_SAFE_INTEGER)
206
+ return envelope_error('', undefined, `factor: '${word}' is not a positive whole number\n`);
207
+ const factors = n === 1 ? [] : factors_of(n);
208
+ data.push({ n, factors });
209
+ lines.push(`${n}: ${factors.join(' ')}`.trimEnd());
210
+ }
211
+ return envelope_ok(`${lines.join('\n')}\n`, { kind: 'games.factor', data: { numbers: data } });
212
+ }
213
+ /** `primes [FROM] TO` */
214
+ export async function builtin_primes(args) {
215
+ const nums = args.map(Number);
216
+ if (nums.length === 0 || nums.length > 2 || nums.some((n) => !Number.isInteger(n))) {
217
+ return envelope_error('', undefined, 'primes: usage: primes [FROM] TO\n');
218
+ }
219
+ const [from, to] = nums.length === 1 ? [2, nums[0]] : [nums[0], nums[1]];
220
+ const primes = primes_between(from, to);
221
+ const note = primes.length >= PRIMES_MAX ? `primes: stopped at ${PRIMES_MAX}\n` : '';
222
+ return envelope_ok(`${primes.join(' ')}\n${note}`, { kind: 'games.primes', data: { from, to, primes } });
223
+ }
224
+ /** `roll [NdS[+M]]...` — 1d6 when bare. */
225
+ export async function builtin_roll(args) {
226
+ const specs = args.length === 0 ? ['1d6'] : args;
227
+ const lines = [];
228
+ const data = [];
229
+ for (const spec of specs) {
230
+ const r = dice_roll(spec);
231
+ if ('refusal' in r)
232
+ return envelope_error('', undefined, `${r.refusal}\n`);
233
+ const mod = r.modifier === 0 ? '' : ` ${r.modifier > 0 ? '+' : '-'} ${Math.abs(r.modifier)}`;
234
+ lines.push(r.rolls.length === 1 && r.modifier === 0 ? `${spec}: ${r.total}` : `${spec}: ${r.rolls.join(' + ')}${mod} = ${r.total}`);
235
+ data.push({ dice: spec, rolls: r.rolls, total: r.total });
236
+ }
237
+ return envelope_ok(`${lines.join('\n')}\n`, { kind: 'games.roll', data: { rolls: data } });
238
+ }
239
+ /** `calc EXPRESSION` */
240
+ export async function builtin_calc(args) {
241
+ const expression = text_input(args);
242
+ if (expression === null)
243
+ return envelope_error('', undefined, 'calc: usage: calc <expression> (e.g. calc 2^10, calc sqrt(2)*pi)\n');
244
+ try {
245
+ const value = calc_evaluate(expression.trim());
246
+ const shown = Number.isInteger(value) ? String(value) : String(Number(value.toPrecision(12)));
247
+ return envelope_ok(`${shown}\n`, { kind: 'games.calc', data: { expression: expression.trim(), value } });
248
+ }
249
+ catch (error) {
250
+ return envelope_error('', undefined, `${error instanceof Error ? error.message : String(error)}\n`);
251
+ }
252
+ }
253
+ /** `units VALUE FROM [to] TO` */
254
+ export async function builtin_units(args) {
255
+ // `units 10 mm to in`, `units 10 mm in in`: the joining word is dropped.
256
+ const words = args.length === 4 && /^(to|in|as)$/i.test(args[2]) ? [args[0], args[1], args[3]] : [...args];
257
+ if (words.length === 1 && (words[0] === 'list' || words[0] === '--list')) {
258
+ return envelope_ok(`${units_known().join(' ')}\n`, { kind: 'games.units', data: { known: units_known() } });
259
+ }
260
+ if (words.length !== 3 || !Number.isFinite(Number(words[0]))) {
261
+ return envelope_error('', undefined, 'units: usage: units VALUE FROM [to] TO (units list names the units)\n');
262
+ }
263
+ const value = Number(words[0]);
264
+ const r = units_convert(value, words[1], words[2]);
265
+ if ('refusal' in r)
266
+ return envelope_error('', undefined, `${r.refusal}\n`);
267
+ const shown = String(Number(r.value.toPrecision(10)));
268
+ return envelope_ok(`${value} ${words[1]} = ${shown} ${words[2]}\n`, { kind: 'games.units', data: { value, from: words[1], to: words[2], result: r.value } });
269
+ }
270
+ //# sourceMappingURL=numbers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"numbers.js","sourceRoot":"","sources":["../../../src/builtins/games/numbers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @file Games played by question and answer: `quiz`, `hangman`, `2048`.
3
+ *
4
+ * Each turn is a question the kernel asks the surface — the console in a
5
+ * terminal, the console's ask bar in ARGUS — so the same game plays
6
+ * anywhere a question can be answered. The boards and the scoring are pure
7
+ * functions, tested apart from the asking.
8
+ *
9
+ * @module
10
+ */
11
+ import { CommandEnvelope } from '@fnndsc/cumin';
12
+ /** One question and its acceptable answers (matched without case or punctuation). */
13
+ export interface QuizItem {
14
+ q: string;
15
+ a: ReadonlyArray<string>;
16
+ }
17
+ /** The bank: the lab's own vocabulary. */
18
+ export declare const QUIZ_BANK: ReadonlyArray<QuizItem>;
19
+ /** How many a round asks. */
20
+ export declare const QUIZ_ROUND: number;
21
+ /** Whether an answer matches: case, spaces and punctuation set aside. */
22
+ export declare function answer_matches(given: string, accepted: ReadonlyArray<string>): boolean;
23
+ /** `quiz`: five questions from the bank; the score at the end. */
24
+ export declare function builtin_quiz(_args: string[]): Promise<CommandEnvelope>;
25
+ /** The words: the lab's. */
26
+ export declare const HANGMAN_WORDS: ReadonlyArray<string>;
27
+ /** The gallows, by misses. */
28
+ export declare const GALLOWS: ReadonlyArray<ReadonlyArray<string>>;
29
+ /** The word with the letters not yet guessed hidden. */
30
+ export declare function word_mask(word: string, guessed: ReadonlySet<string>): string;
31
+ /** `hangman`: a word from the lab, six misses allowed. */
32
+ export declare function builtin_hangman(_args: string[]): Promise<CommandEnvelope>;
33
+ /** A 4×4 board, 0 for empty. */
34
+ export type Board = number[][];
35
+ /** Slides and merges one row to the left; returns the row and the points scored. */
36
+ export declare function row_slide(row: number[]): {
37
+ row: number[];
38
+ score: number;
39
+ };
40
+ /** Moves the whole board; returns the new board, the points, and whether anything moved. */
41
+ export declare function board_move(board: Board, direction: 'left' | 'right' | 'up' | 'down'): {
42
+ board: Board;
43
+ score: number;
44
+ moved: boolean;
45
+ };
46
+ /** Puts a 2 (or, one time in ten, a 4) on an empty cell; false when there is none. */
47
+ export declare function board_spawn(board: Board, random?: () => number): boolean;
48
+ /** Whether any move is left. */
49
+ export declare function board_canMove(board: Board): boolean;
50
+ /** The board drawn. */
51
+ export declare function board_render(board: Board, score: number): string;
52
+ /** `2048`: w/a/s/d (or h/j/k/l) by question, q to stop. */
53
+ export declare function builtin_2048(_args: string[]): Promise<CommandEnvelope>;