UNPKG

cli-prep

Version:

A fun and interactive command-line interview preparation game to test your programming knowledge with 80+ questions across multiple categories!

192 lines (158 loc) • 6.67 kB
#! /usr/bin/env node import chalk from 'chalk'; import chalkAnimation from 'chalk-animation'; import gradient from 'gradient-string'; import figlet from 'figlet'; import inquirer from 'inquirer'; import { createSpinner } from 'nanospinner'; import { questionBank } from './questions.js'; import { getPersonalizedFeedback, getCategoryAnalysis, getMotivationalMessage } from './feedback.js'; let playerName; let score = 0; let currentQuestion = 0; let selectedQuestions = []; let numQuestions = 0; let categoryStats = {}; const sleep = (ms = 1000) => new Promise(resolve => setTimeout(resolve, ms)); // Function to shuffle array function shuffleArray(array) { const shuffled = [...array]; for (let i = shuffled.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; } return shuffled; } // Function to get random questions function getRandomQuestions(count) { const shuffled = shuffleArray(questionBank); return shuffled.slice(0, count); } async function welcome() { const rainbowTitle = chalkAnimation.rainbow('Welcome to the CLI Prep Game!'); await sleep(2000); rainbowTitle.stop(); console.log(chalk.blueBright(figlet.textSync('CLI Prep', { horizontalLayout: 'full' }))); console.log(chalk.cyan(`šŸŽÆ Test your knowledge with ${questionBank.length}+ programming questions!`)); console.log(chalk.yellow('šŸ“š Categories: Algorithms, Data Structures, JavaScript, Web Dev, and more!\n')); } async function askName() { const answers = await inquirer.prompt({ name: 'player_name', type: 'input', message: 'What is your name?', default() { return 'Player'; } }); playerName = answers.player_name; console.log(chalk.green(`Hello, ${playerName}! Let's get started!`)); } async function askNumberOfQuestions() { const answer = await inquirer.prompt({ name: 'num_questions', type: 'input', message: `How many questions would you like to practice? (1-${questionBank.length}):`, default: '10', validate: (input) => { const num = parseInt(input); if (isNaN(num) || num < 1 || num > questionBank.length) { return `Please enter a number between 1 and ${questionBank.length}`; } return true; } }); numQuestions = parseInt(answer.num_questions); selectedQuestions = getRandomQuestions(numQuestions); // Initialize category stats selectedQuestions.forEach(q => { categoryStats[q.category] = categoryStats[q.category] || { correct: 0, total: 0 }; categoryStats[q.category].total++; }); console.log(chalk.yellowBright(`\nšŸŽ² Great! I've selected ${numQuestions} random questions for you.\n`)); } async function askQuestion(questionData) { const question = { name: 'answer', type: 'list', message: `Question ${currentQuestion + 1}/${numQuestions}: ${questionData.question}`, choices: questionData.choices }; const answer = await inquirer.prompt(question); return answer.answer; } async function checkAnswer(userAnswer, correctAnswer, category) { const spinner = createSpinner('Checking your answer...').start(); await sleep(1000); if (userAnswer === correctAnswer) { score++; categoryStats[category].correct++; spinner.success({ text: `Correct, ${playerName}! šŸŽ‰ Score: ${score}/${numQuestions}` }); return true; } else { spinner.error({ text: `Wrong answer, ${playerName}. The correct answer is: ${correctAnswer} āŒ Score: ${score}/${numQuestions}` }); return false; } } async function playGame() { console.log(chalk.yellowBright(`Let's start the quiz, ${playerName}! You have ${numQuestions} questions to answer.\n`)); for (let i = 0; i < selectedQuestions.length; i++) { currentQuestion = i; const questionData = selectedQuestions[i]; // Show category console.log(chalk.magenta(`šŸ“‚ Category: ${questionData.category}`)); const userAnswer = await askQuestion(questionData); await checkAnswer(userAnswer, questionData.correctAnswer, questionData.category); if (i < selectedQuestions.length - 1) { await sleep(1000); console.log(chalk.cyan('\n' + '='.repeat(50) + '\n')); } } await showResults(); } async function showResults() { console.log('\n' + '='.repeat(60)); console.log(chalk.magentaBright(`\nšŸŽÆ QUIZ RESULTS FOR ${playerName.toUpperCase()}`)); console.log('='.repeat(60)); const percentage = (score / numQuestions) * 100; const { performanceLevel, emoji, feedback, suggestions } = getPersonalizedFeedback(score, numQuestions, playerName); // Overall Score console.log(chalk.whiteBright(`šŸ“Š Final Score: ${score}/${numQuestions} (${percentage.toFixed(1)}%)`)); console.log(chalk.yellowBright(`šŸ… Performance Level: ${performanceLevel} ${emoji}\n`)); // Personalized Feedback console.log(chalk.greenBright(`šŸ’¬ Personal Feedback:`)); console.log(chalk.white(` ${feedback}\n`)); // Category Breakdown console.log(chalk.blueBright(`šŸ“ˆ Category Analysis:`)); const categoryAnalysis = getCategoryAnalysis(categoryStats, chalk); categoryAnalysis.forEach(line => console.log(line)); // Suggestions console.log(chalk.yellowBright(`\nšŸ’” Suggestions for Improvement:`)); suggestions.forEach((suggestion, index) => { console.log(chalk.white(` ${index + 1}. ${suggestion}`)); }); if (percentage >= 80) { await winner(); } else { console.log(getMotivationalMessage(percentage, chalk)); } console.log(chalk.greenBright(`\nšŸ™ Thanks for playing, ${playerName}!`)); console.log(gradient('blue', 'purple')('šŸš€ Keep coding and never stop learning! šŸš€')); } // Winner Function using figlet and chalk-animation async function winner() { console.clear(); const msg = chalkAnimation.rainbow('Congratulations! šŸ†'); await sleep(2000); msg.stop(); console.log(chalk.yellowBright(figlet.textSync('WINNER!', { horizontalLayout: 'full' }))); console.log(gradient.pastel.multiline('You have mastered the CLI Prep Game!\nExcellent performance! 🌟')); } async function main() { await welcome(); await askName(); await askNumberOfQuestions(); await playGame(); } // Start the application main().catch(console.error);