Added Magic 8-Ball game.
This commit is contained in:
0
src/app.js
Normal file → Executable file
0
src/app.js
Normal file → Executable file
102
src/games/8ball.js
Normal file
102
src/games/8ball.js
Normal 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
0
src/games/cursed.js
Normal file → Executable file
0
src/games/dice.js
Normal file → Executable file
0
src/games/dice.js
Normal file → Executable file
0
src/games/duck.js
Normal file → Executable file
0
src/games/duck.js
Normal file → Executable file
0
src/games/help.js
Normal file → Executable file
0
src/games/help.js
Normal file → Executable file
0
src/games/kill.js
Normal file → Executable file
0
src/games/kill.js
Normal file → Executable file
0
src/games/letters.js
Normal file → Executable file
0
src/games/letters.js
Normal file → Executable file
0
src/games/mash.js
Normal file → Executable file
0
src/games/mash.js
Normal file → Executable file
0
src/games/ping.js
Normal file → Executable file
0
src/games/ping.js
Normal file → Executable file
0
src/games/rock-paper-scissors.js
Normal file → Executable file
0
src/games/rock-paper-scissors.js
Normal file → Executable file
0
src/games/say.js
Normal file → Executable file
0
src/games/say.js
Normal file → Executable file
0
src/games/trivia.js
Normal file → Executable file
0
src/games/trivia.js
Normal file → Executable file
0
src/games/uptime.js
Normal file → Executable file
0
src/games/uptime.js
Normal file → Executable file
0
src/irc.js
Normal file → Executable file
0
src/irc.js
Normal file → Executable file
6
src/play.js
Normal file → Executable file
6
src/play.js
Normal file → Executable 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
0
src/schat.js
Normal file → Executable file
0
src/utils/get-leaders.js
Normal file → Executable file
0
src/utils/get-leaders.js
Normal file → Executable file
0
src/utils/get-word-key.js
Normal file → Executable file
0
src/utils/get-word-key.js
Normal file → Executable file
0
src/utils/pick-random.js
Normal file → Executable file
0
src/utils/pick-random.js
Normal file → Executable file
0
src/utils/shuffle.js
Normal file → Executable file
0
src/utils/shuffle.js
Normal file → Executable file
2
src/utils/style.js
Normal file → Executable file
2
src/utils/style.js
Normal file → Executable 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 = {
|
||||
|
||||
Reference in New Issue
Block a user