schat2-clive/src/games/8ball.js

111 lines
2.9 KiB
JavaScript

'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 me see...',
'Let me give that some thought',
'🤔',
'💭',
];
const answersByType = {
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 answers = Object.entries(answersByType).flatMap(([type, typeAnswers]) => typeAnswers.map((answer) => ({ answer, type })));
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\p{P}]+\s+[\w\p{P}]+\?/u.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 similarQuestionType = similarQuestion?.rating > 0.6 && questions.get(similarQuestion.target)?.type;
const { answer, type } = similarQuestionType
? {
answer: answersByType[similarQuestionType][crypto.randomInt(0, answersByType[similarQuestionType].length)],
type: similarQuestionType,
}
: answers[crypto.randomInt(0, answers.length)];
questions.set(question, { type, 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.navy('◥')}${style.bgnavy(style.white(` ${answer} `))}${style.navy('◤')}`, context.room.id, {
label: false,
style: {
color: config.schatColors.blue,
// background: config.schatColors.navy,
},
});
purgeQuestions();
}
/* AI chat module is listening instead
function onMessage(message, context) {
const regex = new RegExp(`^${config.usernamePrefix}?${config.user.username}[\\s\\p{P}]*\\s+[\\w\\p{P}]+\\s+[\\w, \\p{P}]+.*\\?`, 'ui');
if (regex.test(message.body)) {
onCommand([message.body.replaceAll(`${config.usernamePrefix}${config.user.username}:?`, '').trim()], context, false);
}
}
*/
module.exports = {
onCommand,
// onMessage,
};