UNPKG

csc-tools

Version:

Tools for Cincinnati Smash Classic

113 lines (99 loc) 3.12 kB
#!/usr/bin/env node const _ = require('lodash'); const program = require('commander'); const getStdin = require('get-stdin'); const path = require('path'); const pify = require('pify'); const colors = require('colors'); const cliff = require('cliff'); const readFile = pify(require('fs').readFile); const csvParse = pify(require('csv-parse')); const csvStringify = pify(require('csv-stringify')); const cscTools = require('../lib'); const pkg = require('../package.json'); function parsePoolCount(str) { let result = _.parseInt(str); if (result > 0) return result; console.error('poolCount must be a positive integer'); process.exit(1); } function getInput(inputPath) { if (!inputPath) return getStdin(); return readFile(path.resolve(process.cwd(), inputPath)); } function getPlayers(inputPath) { return getInput(inputPath) .then((input) => csvParse(input, { auto_parse: true, columns: true })); } program .version(pkg.version); program .command('analyze <poolCount> [path]') .alias('a') .description('analyze a player list') .option('-r, --show-region-counts', 'Show region counts') .option('-p, --show-pools', 'Show pools') .action((poolCount, inputPath, options) => { poolCount = parsePoolCount(poolCount); getPlayers(inputPath) .then((players) => { let analysis = cscTools.analyze(players, poolCount); let base = _.omit(analysis, [ 'pools', 'regionCounts' ]); let { pools, regionCounts } = analysis; let baseRows = _.map(base, (value, key) => [ colors.cyan(`${key}:`), value ]); let regionCountRows = _.map(regionCounts, (count, region) => [ colors.cyan(`${region}:`), count ]); console.log(cliff.stringifyRows(baseRows)); if (options.showRegionCounts) { console.log(colors.yellow.underline('\nRegion Counts')); console.log(cliff.stringifyRows(regionCountRows)); } if (options.showPools) { pools.forEach((pool, index) => { let { players, collisionScore } = pool; let poolLabel = colors.yellow.underline(`Pool ${index + 1}`); let scoreStr = `(collisionScore: ${collisionScore})`; let playerTable = cliff.stringifyObjectRows( players, [ 'tag', 'rank', 'region' ], [ 'cyan', 'cyan', 'cyan' ] ); if (collisionScore > analysis.minPoolCollisionScore) { scoreStr = colors.red(scoreStr); } else { scoreStr = colors.green(scoreStr); } console.log(`\n${poolLabel} ${scoreStr}\n${playerTable}`); }); } }) .catch((err) => { console.error(err); process.exit(1); }); }); program .command('solve <poolCount> [path]') .alias('s') .description('minimize regional collisions in a player list') .action((poolCount, inputPath) => { poolCount = parsePoolCount(poolCount); getPlayers(inputPath) .then((players) => { let solution = cscTools.solve(players, poolCount); return csvStringify(solution, { header: true }); }) .then((output) => { process.stdout.write(output); }) .catch((err) => { console.error(err); process.exit(1); }); }); program.parse(process.argv);