markov chain minigame

This commit is contained in:
Jill 2023-05-04 01:17:15 +03:00
parent 71346db817
commit 2f06489e13
Signed by: oat
GPG Key ID: 33489AA58A955108
3 changed files with 140 additions and 2 deletions

6
.gitignore vendored
View File

@ -5,5 +5,7 @@ subscriptions.json
node_modules
tsconfig.tsbuildinfo
built/*
counter.json
counterMessageID.txt
/counter.json
/counterMessageID.txt
/counterCream.json
/counterCreamMessageID.txt

135
src/commands/markov.ts Normal file
View File

@ -0,0 +1,135 @@
import { SlashCommandBuilder } from '@discordjs/builders';
import { CommandInteraction, GuildMember, Message, User } from 'discord.js';
const DEFAULT_EMOJI = '🪙';
const STOP_EMOJI = '⏹️';
const DONE_EMOJI = '👍';
const END_TEMPLATES = [
'Alright! Here\'s the messages you all conjured:',
'Here are the abominations you all have made:',
'Time\'s up! Here\'s what you\'ve managed to achieve:',
'That does it! Here\'s what you\'ve all cooked up together:'
];
const RANDOM_WORDS = [
'tarsorado', 'aboba', 'robtop', 'viprin', 'milk', 'milking station', 'radiation', 'extreme', 'glogging', 'glogged',
'penis', 'deadlocked', 'cream', 'dragon cream', 'urine', 'communal', 'piss', 'matpat', 'big and round', 'easy',
'cum', 'glue', 'tampon', 'contaminated water', 'centrifuge', 'inflation', 'plutonium', 'uranium', 'thorium',
'imposter', 'sounding', '💥', '🥵', '🎊', '!!!', '...', '???', '?..', '?!', '!', '?', 'balls itch', 'robert',
'gas leak', 'among us', 'stick a finger', 'overclock', 'breed', 'gay sex', 'breedable', 'cock vore', 'appendix',
'mukbang', 'edging', 'onlyfans', 'productive', 'mandelbrot', 'novosibirsk', 'oops!', 'farting', 'memory leak',
'pepsi can'
];
function formatMessage(users: User[], time: number) {
return `Starting a Markov chain game (${users.length} player${users.length !== 1 ? 's' : ''})\n`
+ users.map(user => `- ${user.toString()}`).join('\n') + '\n'
+ (time <= 0 ?
'**Already started**' :
`Starting in **${Math.ceil(time / 1000)}s** - react ${STOP_EMOJI} to begin now`
);
}
function randomWord() {
return RANDOM_WORDS[Math.floor(Math.random() * RANDOM_WORDS.length)];
}
module.exports = {
data: new SlashCommandBuilder()
.setName('markov')
.setDescription('Play a Markov chain game')
.addIntegerOption((option) =>
option
.setName('context')
.setRequired(false)
.setDescription('Amount of words to show as context')
.setMinValue(1)
),
execute: async (interaction: CommandInteraction, member: GuildMember) => {
let participants: User[] = [member.user];
const context = interaction.options.getInteger('context') || 3;
const duration = 25000;
const m = await interaction.reply({
fetchReply: true,
content: formatMessage(participants, duration)
});
if (!(m instanceof Message)) return;
const emoji = m.guild?.emojis.cache.random();
await m.react(emoji || DEFAULT_EMOJI);
await m.react(STOP_EMOJI);
const started = Date.now();
const collector = m.createReactionCollector({
filter: (reaction, user) =>
!user.bot && (
(
(emoji ? reaction.emoji.id === emoji.id : reaction.emoji.name === DEFAULT_EMOJI) &&
!participants.find(u => user.id === u.id)
) || (reaction.emoji.name === STOP_EMOJI && user.id === member.id)
),
time: duration,
dispose: true
});
collector.on('collect', (reaction, user) => {
if (reaction.emoji.name === STOP_EMOJI) {
collector.stop();
} else {
participants.push(user);
m.edit(formatMessage(participants, duration - (Date.now() - started)));
}
});
collector.on('remove', (_, user) => {
participants = participants.filter(u => u.id !== user.id);
m.edit(formatMessage(participants, duration - (Date.now() - started)));
});
collector.on('end', async () => {
m.edit(formatMessage(participants, 0));
let sentences: string[][] = Array(participants.length).fill(0);
sentences = sentences.map(() => []);
let iterations = 0;
const maxIterations = 10;
// eslint-disable-next-line no-constant-condition
while (true) {
await Promise.all(
participants.map(async (p, i) => {
const sentence = sentences[(i + iterations) % sentences.length];
const msg = await p.send(`Continue the following sentence: [${iterations}/${maxIterations}]\n\n> _${context < sentence.length ? '…' : ''}${sentence.length > 0 ? sentence.slice(-context).join(' ') : `start a sentence... (try working with: “${randomWord()}”)`}_` + (iterations === 0 ? '\n\n**Send a message to continue**' : ''));
try {
const collected = await msg.channel.awaitMessages({
max: 1,
time: 15000,
errors: ['time']
});
const message = collected.first() as Message;
sentence.push(...message.content.split(' '));
await message.react(DONE_EMOJI);
} catch (err) {
await p.send('Took too long... Surprise... Added...... :)');
sentence.push(...randomWord().split(' '));
}
})
);
iterations++;
if (iterations > maxIterations) {
break;
}
}
const endTemplate = END_TEMPLATES[Math.floor(Math.random() * END_TEMPLATES.length)];
await m.reply(endTemplate + '\n\n' + sentences.map(sentence => '- “' + sentence.join(' ') + '”').join('\n') + '\n\nThank you for participating :)');
});
}
};

View File

@ -15,6 +15,7 @@ const bot = new Discord.Client({
Discord.Intents.FLAGS.GUILD_VOICE_STATES,
Discord.Intents.FLAGS.GUILD_MESSAGE_REACTIONS,
Discord.Intents.FLAGS.GUILD_MEMBERS,
Discord.Intents.FLAGS.DIRECT_MESSAGES
],
});