2023-11-16 11:33:11 +01:00
import { GuildMember , SlashCommandBuilder , CommandInteraction , messageLink } from 'discord.js' ;
2023-10-29 10:22:23 +01:00
import { getTextResponsePrettyPlease , randomWord , sendSegments , startGame } from '../lib/game' ;
2023-11-16 11:33:11 +01:00
import { Command } from '../types/index' ;
2023-05-04 00:17:15 +02:00
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:'
] ;
2023-11-16 11:33:11 +01:00
export default {
2023-05-04 00:17:15 +02:00
data : new SlashCommandBuilder ( )
. setName ( 'markov' )
. setDescription ( 'Play a Markov chain game' )
2023-10-25 23:43:23 +02:00
. addIntegerOption ( option = >
2023-05-04 00:17:15 +02:00
option
. setName ( 'context' )
. setRequired ( false )
. setDescription ( 'Amount of words to show as context' )
. setMinValue ( 1 )
2023-10-25 23:43:23 +02:00
. setMaxValue ( 100 )
)
. addIntegerOption ( option = >
option
. setName ( 'iterations' )
. setRequired ( false )
. setDescription ( 'Amount of rounds to do' )
. setMinValue ( 1 )
. setMaxValue ( 100 ) ) ,
2023-05-04 00:17:15 +02:00
2023-11-16 11:33:11 +01:00
execute : async ( interaction : CommandInteraction ) = > {
2023-06-11 17:23:57 +02:00
if ( ! interaction . isChatInputCommand ( ) ) return ;
2023-11-16 11:33:11 +01:00
const member = interaction . member ! as GuildMember ;
2023-05-04 00:17:15 +02:00
const context = interaction . options . getInteger ( 'context' ) || 3 ;
2023-10-25 23:43:23 +02:00
const maxIterations = interaction . options . getInteger ( 'iterations' ) || 10 ;
2023-05-04 00:17:15 +02:00
2023-10-29 11:11:07 +01:00
startGame ( interaction , member . user , 'Markov Chain' , async ( participants , channel ) = > {
2023-05-04 00:17:15 +02:00
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 ] ;
2023-10-29 10:22:23 +01:00
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 ( ' ' ) ) ;
2023-05-04 00:17:15 +02:00
} )
) ;
iterations ++ ;
if ( iterations > maxIterations ) {
break ;
}
}
const endTemplate = END_TEMPLATES [ Math . floor ( Math . random ( ) * END_TEMPLATES . length ) ] ;
2023-10-25 23:43:23 +02:00
const segments = [
2023-10-29 11:11:07 +01:00
endTemplate + '\n' ,
2023-10-25 23:43:23 +02:00
. . . sentences . map ( sentence = > '- ' + sentence . join ( ' ' ) ) ,
2023-10-29 11:11:07 +01:00
'\nThank you for participating :)'
2023-10-25 23:43:23 +02:00
] ;
2023-10-29 11:11:07 +01:00
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 ) } ` ) ;
} ) ;
2023-05-04 00:17:15 +02:00
} ) ;
}
2023-11-16 11:33:11 +01:00
} satisfies Command ;