UNPKG

console-fun

Version:

Some stuff in the console: utils, printing, games and other fun

146 lines (128 loc) 4.29 kB
import readline from "readline"; import figureSet from "figures"; import logUpdate from "log-update"; import ansiEscapes from "ansi-escapes"; import chalk from "chalk"; import { shuffle } from "fast-shuffle"; import delay from "delay"; import { repeat, join } from "rambda"; import { repeatString } from "../utils"; const start = async (roundFigure, { size }) => { let score = 0; let currInd = 0; let currentFigure = ""; let currentColor = chalk.green; let currentCorrectIndex = 0; const correctIndexes = []; const answeredIndexes = []; const gridSize = size || 8; readline.emitKeypressEvents(process.stdin); process.stdin.setRawMode(true); process.stdin.on("keypress", (_chunk, key) => { if (key && key.name == "q") { process.exit(); } else if (key && key.name == "n") { if (currentFigure === roundFigure) { const lastIndex = correctIndexes[correctIndexes.length - 1]; if (!answeredIndexes.includes(lastIndex)) { score++; answeredIndexes.push(lastIndex); logUpdate(getString()); } } } else if (key.name === "space") { if (currentFigure === roundFigure) { const lastIndex = correctIndexes[correctIndexes.length - 1]; if (!answeredIndexes.includes(lastIndex)) { score++; answeredIndexes.push(lastIndex); logUpdate(getString()); } } } else if (key.name === "down") { } else if (key.name === "up") { process.exit(); } else if (key.name === "s" || key.name === "return") { } else if ("12345678a9".includes(key.name)) { score++; } }); const items = []; for (let i = 0; i < gridSize; i++) { for (let j = 0; j < gridSize; j++) { let rndIndex = Math.floor(Math.random() * gridSize); if (j === rndIndex) { items.push([i, j, figureSet.circle, true]); } else { const figureToInsert = shuffle([ figureSet.triangleLeft, figureSet.triangleRight, figureSet.triangleDown, figureSet.triangleUp, ])[0]; items.push([i, j, figureToInsert]); } } process.stdout.write(ansiEscapes.cursorTo(0, 0)); process.stdout.write(ansiEscapes.eraseScreen); process.stdout.write(ansiEscapes.cursorNextLine); process.stdout.write(figureSet.home); } let lineOffset = 10; let displayable = join("", repeat(" ", lineOffset)); const getString = () => { return ` Press ${chalk.bold("[space]")} on '${roundFigure}' appearance. Score: ${score} ${displayable} `; }; let columnCounter = 0; for (let y = 0; y < items.length; y++) { currentColor = y % 2 === 0 ? chalk.cyan : chalk.red; currentFigure = `${items[y][2]}`; if (currentFigure === roundFigure) { correctIndexes.push(currentCorrectIndex); } if (displayable === "") { displayable = ""; } displayable += ` ${currentColor(currentFigure)} `; if (columnCounter + 1 >= gridSize) { displayable += `\n${join("", repeat(" ", lineOffset))}`; currInd = y; columnCounter = -1; } logUpdate(getString()); await delay(items[y][2] === figureSet.heart ? 600 : 450); columnCounter++; currentCorrectIndex++; } logUpdate(getString()); }; const watchFigureGame = async ({ size }) => { const roundFigure = figureSet.circle; readline.emitKeypressEvents(process.stdin); process.stdin.setRawMode(true); process.stdin.on("keypress", async (_chunk, key) => { if (key && key.name == "q") { process.exit(); } else if (key && key.name == "y") { if (size) { await start(roundFigure, { size }); } else { await start(roundFigure); } } }); process.stdout.write(ansiEscapes.clearScreen); process.stdout.write(repeatString(" ", 26) + chalk.green("watch-figure")); process.stdout.write(repeatString(ansiEscapes.cursorNextLine, 4)); process.stdout.write(` There are different figures are appearing during a game round. Your task is to watch the ${roundFigure} figure appearance and press ${chalk.bold("[space]")} before the next figure has been shown. Start ${chalk.bold.green("y")} if you are ready. `); }; export { watchFigureGame };