| 1 | // A bot's own process: node referee/bot.mjs <bot folder>. Loads <bot folder>/bot.mjs, whose default export (or `act`) |
| 2 | // is act(obs, legal) -> move, and answers the referee one JSON line per ask: {n, obs, legal} in, {n, answer} out. |
| 3 | // A bot's prints go to stderr, so they cannot corrupt the channel. |
| 4 | import { createInterface } from 'node:readline'; |
| 5 | import path from 'node:path'; |
| 6 | import { pathToFileURL } from 'node:url'; |
| 7 | |
| 8 | const write = process.stdout.write.bind(process.stdout); |
| 9 | console.log = console.info = console.debug = console.warn = console.error; |
| 10 | process.stdout.write = process.stderr.write.bind(process.stderr); |
| 11 | |
| 12 | const mod = await import(pathToFileURL(path.join(process.argv[2], 'bot.mjs')).href); |
| 13 | const act = mod.default ?? mod.act; |
| 14 | for await (const line of createInterface({ input: process.stdin })) { |
| 15 | let m, answer = null; |
| 16 | try { |
| 17 | m = JSON.parse(line); |
| 18 | answer = m.hello ? true : await act(m.obs, m.legal); |
| 19 | } catch (e) { |
| 20 | console.error(e); |
| 21 | } |
| 22 | write(`${JSON.stringify({ n: m?.n, answer: answer ?? null })}\n`); |
| 23 | } |
