jillo-bot/src/commands/markov.ts

78 lines
2.9 KiB
TypeScript

import { GuildMember, SlashCommandBuilder, CommandInteraction, messageLink } from 'discord.js';
import { getTextResponsePrettyPlease, randomWord, sendSegments, startGame } from '../lib/game';
import { Command } from '../types/index';
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:'
];
export default {
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)
.setMaxValue(100)
)
.addIntegerOption(option =>
option
.setName('iterations')
.setRequired(false)
.setDescription('Amount of rounds to do')
.setMinValue(1)
.setMaxValue(100)),
execute: async (interaction: CommandInteraction) => {
if (!interaction.isChatInputCommand()) return;
const member = interaction.member! as GuildMember;
const context = interaction.options.getInteger('context') || 3;
const maxIterations = interaction.options.getInteger('iterations') || 10;
startGame(interaction, member.user, 'Markov Chain', async (participants, channel) => {
let sentences: string[][] = Array(participants.length).fill(0);
sentences = sentences.map(() => []);
let iterations = 0;
// 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 prompt = (`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**' : '')).slice(0, 2000);
const resp = await getTextResponsePrettyPlease(p, prompt);
sentence.push(...resp.split(' '));
})
);
iterations++;
if (iterations > maxIterations) {
break;
}
}
const endTemplate = END_TEMPLATES[Math.floor(Math.random() * END_TEMPLATES.length)];
const segments = [
endTemplate + '\n',
...sentences.map(sentence => '- ' + sentence.join(' ')),
'\nThank you for participating :)'
];
const messages = await sendSegments(segments, channel);
participants.forEach(player => {
player.send(`**The game has concluded!** See your results here: ${messageLink(messages[0].channelId, messages[0].id)}`);
});
});
}
} satisfies Command;