/** * Trivia Bot Example * * A bot that runs trivia games in chat * * Usage: * node trivia-bot.js * * Commands: * !trivia start - Start a new trivia game * !trivia stop - Stop the current game * !trivia score - Show current scores * !answer - Submit an answer */ import ChatBot from '../index.js'; // Get arguments const [,, apiKey, serverUrl, realmId] = process.argv; if (!apiKey || !serverUrl || !realmId) { console.log('Usage: node trivia-bot.js '); process.exit(1); } // Trivia questions const questions = [ { question: "What planet is known as the Red Planet?", answer: "mars" }, { question: "What is the largest mammal in the world?", answer: "blue whale" }, { question: "In what year did the Titanic sink?", answer: "1912" }, { question: "What is the chemical symbol for gold?", answer: "au" }, { question: "Who painted the Mona Lisa?", answer: "leonardo da vinci" }, { question: "What is the capital of Japan?", answer: "tokyo" }, { question: "How many sides does a hexagon have?", answer: "6" }, { question: "What is the smallest prime number?", answer: "2" }, { question: "What element does 'O' represent on the periodic table?", answer: "oxygen" }, { question: "In what year did World War II end?", answer: "1945" }, { question: "What is the largest organ in the human body?", answer: "skin" }, { question: "Who wrote Romeo and Juliet?", answer: "shakespeare" }, { question: "What is the speed of light in km/s (approximately)?", answer: "300000" }, { question: "What is the tallest mountain in the world?", answer: "everest" }, { question: "What gas do plants absorb from the atmosphere?", answer: "carbon dioxide" } ]; // Game state let gameActive = false; let currentQuestion = null; let questionIndex = 0; let scores = {}; let questionTimeout = null; let usedQuestions = []; // Create the bot const bot = new ChatBot('TriviaBot'); 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 getNextQuestion() { if (usedQuestions.length === questions.length) { usedQuestions = []; } const available = questions.filter((_, i) => !usedQuestions.includes(i)); const randomIndex = Math.floor(Math.random() * available.length); const originalIndex = questions.indexOf(available[randomIndex]); usedQuestions.push(originalIndex); return available[randomIndex]; } function askQuestion() { if (!gameActive) return; currentQuestion = getNextQuestion(); questionIndex++; bot.print(`Question #${questionIndex}: ${currentQuestion.question}`); // Set timeout for unanswered question questionTimeout = setTimeout(() => { if (currentQuestion) { bot.print(`Time's up! The answer was: ${currentQuestion.answer}`); currentQuestion = null; // Ask next question after delay setTimeout(() => { if (gameActive) askQuestion(); }, 3000); } }, 30000); // 30 seconds to answer } function checkAnswer(username, answer) { if (!currentQuestion) return; const normalizedAnswer = answer.toLowerCase().trim(); const correctAnswer = currentQuestion.answer.toLowerCase().trim(); if (normalizedAnswer === correctAnswer || normalizedAnswer.includes(correctAnswer) || correctAnswer.includes(normalizedAnswer)) { clearTimeout(questionTimeout); // Award points if (!scores[username]) scores[username] = 0; scores[username]++; bot.print(`Correct! ${username} got it right! (+1 point, total: ${scores[username]})`); currentQuestion = null; // Ask next question after delay setTimeout(() => { if (gameActive) askQuestion(); }, 3000); } } function showScores() { const sortedScores = Object.entries(scores) .sort(([, a], [, b]) => b - a) .slice(0, 10); if (sortedScores.length === 0) { bot.print('No scores yet!'); return; } let scoreText = 'Leaderboard: '; sortedScores.forEach(([user, score], i) => { scoreText += `${i + 1}. ${user}: ${score} pts | `; }); bot.print(scoreText.slice(0, -3)); } function startGame() { if (gameActive) { bot.print('A game is already in progress!'); return; } gameActive = true; questionIndex = 0; bot.print('Trivia game starting! Answer with "!answer ". You have 30 seconds per question.'); setTimeout(() => { askQuestion(); }, 2000); } function stopGame() { if (!gameActive) { bot.print('No game is currently running.'); return; } gameActive = false; currentQuestion = null; clearTimeout(questionTimeout); bot.print('Trivia game stopped!'); showScores(); } // Set up message handler bot.messageHandler = (message) => { const content = message.content.trim().toLowerCase(); if (content === '!trivia start') { startGame(); } else if (content === '!trivia stop') { stopGame(); } else if (content === '!trivia score' || content === '!trivia scores') { showScores(); } else if (content === '!trivia help') { bot.print('Commands: !trivia start, !trivia stop, !trivia score, !answer '); } else if (content.startsWith('!answer ')) { const answer = message.content.slice(8); checkAnswer(message.username, answer); } }; // Set up event handlers bot.onJoin = () => { bot.print('TriviaBot is online! Type "!trivia start" to begin a game.'); }; bot.onError = (error) => { console.error('Bot error:', error.message); }; // Connect and join async function main() { try { console.log(`Connecting to ${serverUrl}...`); await bot.connect(apiKey, serverUrl); console.log(`Joining room: ${realmId}...`); await bot.joinRoom(realmId); console.log('TriviaBot is running. Press Ctrl+C to stop.'); } catch (error) { console.error('Failed to start bot:', error.message); process.exit(1); } } // Handle shutdown process.on('SIGINT', () => { console.log('\nShutting down bot...'); if (gameActive) stopGame(); bot.disconnect(); process.exit(0); }); main();