プログラムの概要
Node.js にて、円周率の暗記を手助けするプログラムを書いています。
発生する問題
enquirer という npm を使用しており、以下のようなプロンプトからモードセレクトに移行させるという流れになっています。
>>>>>>>>>> PI GAME <<<<<<<<<< ? Select your mode: … ❯ PRACTICE MODE REAL MODE SHOW PI DIGITS HIGH SCORES
しかしながら、モード選択後に標準入力を受け取りたいのに、入力を待たずにプログラムが終了してしまいます。
原因の予想
enquirer
によって用意したモードセレクトをスキップして、いきなりモードを始めると、意図通りに標準入力を受け付けてくれます。
そのため、原因は、enquirer
により標準入力に関係する何らかの状態が初期状態から変更されてしまった状態のままで、標準入力に関係する処理を実行していることにあるように思います。
お教え頂きたいこと
プロンプトでの選択後、enquirer
での処理による変更を初期状態に戻して、選択したモードに移行するような方法はありますでしょうか?
それが難しければ、モード選択後に、標準入力を適切に扱うような方法があれば、ご教示頂きたいです。
どうぞよろしくお願い致します。
実際のコード
#!/usr/bin/env node 'use strict' { const { Select } = require('enquirer') const chalk = require('chalk') const PI_START_TEXT = '3.' const PI_BELOW_THE_DECIMAL_POINT = '1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679' class PracticeMode { start () { const instruction = 'Keep typing in the number which fits the cursor position.' // この行の出力処理の直後に、プログラムが止まってしまう process.stdout.write(chalk.bold.green(instruction) + '\n\n' + PI_START_TEXT) const readline = require('readline'); readline.emitKeypressEvents(process.stdin) process.stdin.setRawMode(true); let currentIndex = 0 process.stdin.on('keypress', (char, key) => { if (key.ctrl && key.name === 'c') { process.exit(); } else if (currentIndex === 100) { this.putsCongratulations() process.exit(); } else if (char === PI_BELOW_THE_DECIMAL_POINT[currentIndex]) { process.stdout.write(char) currentIndex++ } else { const scoreMessage = `Your score: ${currentIndex}` const remaining_digits_text = this.make_remaining_digits_text(currentIndex) console.log(chalk.red(remaining_digits_text) + '\n' + scoreMessage) process.exit(); } }) } putsCongratulations () { const headSpaces = ' '.repeat(6) const congratulationsSentences = [ 'Congratulations!', 'You have memorized the first 100 digits of pi.' ] let congratulations = '' congratulationsSentences.forEach(sentence => { congratulations += headSpaces + sentence + '\n' }) console.log(chalk.bold.green(congratulations)) } make_remaining_digits_text (currentIndex) { let remaining_digits_text = '' const digitsNum = 100 const sectionDigitsNum = 10 const lineDigitsNum = 50 for (let i = currentIndex; i < digitsNum; i++) { if (i === lineDigitsNum) { remaining_digits_text += '\n' + ' '.repeat(PI_START_TEXT.length) } else if (i % sectionDigitsNum === 0) { remaining_digits_text += ' ' } remaining_digits_text += PI_BELOW_THE_DECIMAL_POINT[i] } return remaining_digits_text } } class Game { constructor () { this.practiceMode = 'PRACTICE MODE' this.showPiDigits = 'SHOW PI DIGITS' this.highScores = 'HIGH SCORES' } start () { const modes = [ { name: this.practiceMode, explanation: 'Check how many digits of pi you can name from the point you designated.' }, { name: this.showPiDigits, explanation: 'Check the first 100 digits of pi.' }, { name: this.highScores, explanation: 'Check the high scores.' } ] const prompt = new Select({ name: 'mode', message: 'Select your mode:', choices: modes.map(mode => mode.name), footer () { const explanations = modes.map(mode => ' '.repeat(2) + mode.explanation) return chalk.green('\n' + explanations[this.index]) } }) prompt.run() .then(answer => { switch (answer) { case this.practiceMode: // 問題が起こっているのは、この PRACTICE MODE 選択時 new PracticeMode().start() break; case this.showPiDigits: break; case this.highScores: break; } }) } } function main () { const welcomeMessage = '>'.repeat(10) + ' PI GAME ' + '<'.repeat(10) console.log(chalk.bold.green(welcomeMessage)) // これが意図通りに動かない new Game().start() // この行を実行すれば、意図通りに動く // new PracticeMode().start() } main() }
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。