Added Magic 8-Ball game.

This commit is contained in:
Niels Simenon
2022-10-28 00:22:00 +02:00
parent 34fb977e77
commit acf60eeca0
104 changed files with 124 additions and 5 deletions

0
src/app.js Normal file → Executable file
View File

102
src/games/8ball.js Normal file
View File

@@ -0,0 +1,102 @@
'use strict';
const config = require('config');
const crypto = require('crypto');
const timers = require('timers/promises');
const stringSimilarity = require('string-similarity');
const style = require('../utils/style');
const contemplations = [
'Hmmm...',
'🤔',
'Let\'s see...',
];
const answers = {
positive: [
'It is certain',
'It is decidedly so',
'Without a doubt',
'Yes definitely',
'You may rely on it',
'As I see it, yes',
'Most likely',
'Outlook good',
'Yes',
'Signs points to yes',
],
inconclusive: [
'Reply hazy, try again',
'Ask again later',
'Better not tell you now',
'Cannot predict now',
'Concentrate and ask again',
],
negative: [
'Don\'t count on it',
'My reply is no',
'My sources say no',
'Outlook not so good',
'Very doubtful',
],
};
const questions = new Map();
function purgeQuestions() {
Array.from(questions.entries()).forEach(([question, { timestamp }]) => {
if (new Date() - timestamp > 5 * 60 * 1000) { // 5 minutes
questions.delete(question);
}
});
}
async function onCommand(args, context) {
const question = args.join(' ');
if (!/\w+\s+\w+\?/.test(question)) {
context.sendMessage('Please ask me a question, any question...', context.room.id);
return;
}
// attempt to give consistent answers between similar questions
const similarQuestion = questions.size > 0
? stringSimilarity.findBestMatch(question, Array.from(questions.keys())).bestMatch
: null;
const answerType = similarQuestion?.rating > 0.5
? questions.get(similarQuestion.target).answerType
: Object.keys(answers)[crypto.randomInt(0, 3)];
const answer = answers[answerType][crypto.randomInt(0, answers[answerType].length)];
questions.set(question, { answerType, timestamp: new Date() });
context.sendMessage(`🎱 ${contemplations[crypto.randomInt(0, contemplations.length)]}`, context.room.id, { label: false });
await timers.setTimeout(Math.random() * 3000 + 1000);
context.sendMessage(style.bgnavy(style.white(`${answer}`)), context.room.id, {
label: false,
style: {
color: config.schatColors.white,
background: config.schatColors.navy,
},
});
purgeQuestions();
}
function onMessage(message, context) {
const regex = new RegExp(`^${config.usernamePrefix}${config.user.username}:?\\s+\\w+\\s+\\w+.*\\?`, 'i');
if (regex.test(message.body)) {
onCommand([message.body.replaceAll(`${config.usernamePrefix}${config.user.username}:?`, '').trim()], context, false);
}
}
module.exports = {
onCommand,
onMessage,
};

0
src/games/cursed.js Normal file → Executable file
View File

0
src/games/dice.js Normal file → Executable file
View File

0
src/games/duck.js Normal file → Executable file
View File

0
src/games/help.js Normal file → Executable file
View File

0
src/games/kill.js Normal file → Executable file
View File

0
src/games/letters.js Normal file → Executable file
View File

0
src/games/mash.js Normal file → Executable file
View File

0
src/games/ping.js Normal file → Executable file
View File

0
src/games/rock-paper-scissors.js Normal file → Executable file
View File

0
src/games/say.js Normal file → Executable file
View File

0
src/games/trivia.js Normal file → Executable file
View File

0
src/games/uptime.js Normal file → Executable file
View File

0
src/irc.js Normal file → Executable file
View File

6
src/play.js Normal file → Executable file
View File

@@ -117,9 +117,9 @@ async function getGames(bot, identifier) {
bot.socket.transmit('message', {
roomId,
recipient,
type: recipient && options.type !== 'message' ? 'whisper' : 'message',
type: recipient && options?.type !== 'message' ? 'whisper' : 'message',
body: curatedBody,
style: config.style,
style: { ...config.style, ...options?.style },
});
}
};
@@ -235,7 +235,7 @@ function onMessage(message, bot, games) {
}
}
if (message.type === 'message') {
if (message.type === 'message' && user.username !== config.user.username) {
Object.values(Object.fromEntries(Object.values(games).map((game) => [game.key, game]))).forEach((game) => game.onMessage?.(message, {
...game,
bot,

0
src/schat.js Normal file → Executable file
View File

0
src/utils/get-leaders.js Normal file → Executable file
View File

0
src/utils/get-word-key.js Normal file → Executable file
View File

0
src/utils/pick-random.js Normal file → Executable file
View File

0
src/utils/shuffle.js Normal file → Executable file
View File

2
src/utils/style.js Normal file → Executable file
View File

@@ -50,7 +50,7 @@ module.exports = (() => {
bold: schatBold,
italic: schatItalic,
code: schatCode,
...Object.fromEntries(Object.entries(config.schatColors).map(([color, value]) => [color, (text) => schatColor(text, value)])),
...Object.fromEntries(Object.entries(config.schatColorAliases).map(([color, value]) => [color, (text) => schatColor(text, value)])),
};
const handler = {