221 lines
6.1 KiB
JavaScript
221 lines
6.1 KiB
JavaScript
/**
|
|
* Trivia Bot Example
|
|
*
|
|
* A bot that runs trivia games in chat
|
|
*
|
|
* Usage:
|
|
* node trivia-bot.js <api-key> <server-url> <realm-id>
|
|
*
|
|
* Commands:
|
|
* !trivia start - Start a new trivia game
|
|
* !trivia stop - Stop the current game
|
|
* !trivia score - Show current scores
|
|
* !answer <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 <api-key> <server-url> <realm-id>');
|
|
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 <your 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 <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();
|