Add node script for calling into fish-cli with fumens

This commit is contained in:
tali 2022-12-16 12:45:47 -05:00
parent 2f80606eb7
commit dfd8d9f399
4 changed files with 135 additions and 0 deletions

2
fumen-utils/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
node_modules
package-lock.json

25
fumen-utils/list.js Normal file
View File

@ -0,0 +1,25 @@
const fumen = require('tetris-fumen');
const { argv } = require('node:process');
const { fumenPageToInputState, fumenPagePlayMove, runFishCli } = require('./src/utils');
async function main() {
if (argv.length != 3) {
throw new Error('usage: node list <url>');
}
let url = argv[2];
let pages = fumen.decoder.decode(url);
if (pages.length !== 1) {
throw new Error('expected exactly one page');
}
let inputState = fumenPageToInputState(pages[0]);
let output = await runFishCli(['list'], inputState);
for (let move of output.moves) {
pages.push(fumenPagePlayMove(pages[0], move, { lock: false }));
}
console.log(fumen.encoder.encode(pages));
}
main().catch(e => console.error(e));

10
fumen-utils/package.json Normal file
View File

@ -0,0 +1,10 @@
{
"name": "fumen-utils",
"version": "1.0.0",
"description": "",
"author": "iitalics",
"license": "LGPL-2.1-or-later",
"dependencies": {
"tetris-fumen": "^1.1.3"
}
}

98
fumen-utils/src/utils.js Normal file
View File

@ -0,0 +1,98 @@
const fumen = require('tetris-fumen');
const { Quiz } = require('tetris-fumen/lib/quiz');
const { Page } = require('tetris-fumen/lib/decoder');
const { env } = require('node:process');
const { spawn } = require('node:child_process');
const path = require('node:path');
function fumenPageToInputState(page) {
let board = new Array(40);
for (let y = 0; y < 23; y++) {
let row = board[y] = new Array(10);
for (let x = 0; x < 10; x++) {
row[x] = page.field.at(x, y);
if (row[x] === '_') {
row[x] = null;
} else if (row[x] === 'X') {
row[x] = 'G';
}
}
}
board[23] = new Array(10);
for (let x = 0; x < 10; x++) {
board[23][x] = null
}
for (let y = 24; y < 40; y++) {
board[y] = board[23];
}
if (!page.flags.quiz) {
throw new Error('page doesnot specify queue');
}
let quiz = new Quiz(page.comment);
let hold = quiz.hold;
let queue = [quiz.current, ...quiz.least];
return {
hold,
queue,
combo: 0,
back_to_back: 0,
board,
};
}
function fumenPagePlayMove(page, move, flags) {
let quiz = new Quiz(page.comment);
// console.log(`${move.location.x},${move.location.y},${move.location.orientation[0]}`);
return {
operation: {
type: move.location.type,
x: move.location.x,
y: move.location.y,
rotation: {
'north': 'spawn',
'east': 'right',
'south': 'reverse',
'west': 'left',
}[move.location.orientation],
},
flags,
};
}
function runFishCli(args, input, cmd = getFishCliPath()) {
let fish = spawn(cmd, args, { stdio: ['pipe', 'pipe', 'inherit'] });
let data = [];
let output = null;
fish.stdout.on('data', (buf) => data.push(buf));
fish.stdout.on('end', () => {
output = JSON.parse(Buffer.concat(data).toString());
});
let exitPromise = new Promise((res, rej) => {
fish.on('exit', (code) => {
if (code === 0) {
res(output);
} else {
rej(new Error(`exit code: ${code}`));
}
});
});
if (input !== undefined) {
fish.stdin.end(JSON.stringify(input));
}
return exitPromise;
}
function getFishCliPath() {
return process.env['FISH_CLI'] || path.join(__dirname, '../../target/release/fish-cli');
}
module.exports = {
fumenPageToInputState,
fumenPagePlayMove,
runFishCli,
};