UNPKG

djs-systems

Version:

The simplest way to build complex Discord bots.

943 lines 64.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.tictactoe = void 0; const discord_js_1 = require("discord.js"); const misc_1 = require("./misc"); const error_1 = require("./error"); const limiter = []; // ------------------------------ // ------ F U N C T I O N ------- // ------------------------------ const combinations = [ [0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6] ]; /** * One line implementation of a super enjoyable **tictactoe game**. * @param message * @param options * @link `Documentation:` https://simplyd.js.org/docs/Fun/tictactoe * @example simplydjs.tictactoe(interaction) */ async function tictactoe(message, options = { max: 6, strict: false }) { return new Promise(async (resolve) => { try { const { client } = message; let interaction; if (message.commandId) { interaction = message; if (!interaction.deferred) await interaction.deferReply({ fetchReply: true }); } let opponent; const extInteraction = message; const extMessage = message; let id = limiter.findIndex((a) => a.guild == message.guild.id); if (!limiter[id] || !limiter[id].guild) { limiter.push({ guild: message.guild.id, limit: 0 }); id = limiter.findIndex((a) => a.guild == message.guild.id); } if (limiter[id].limit >= (options?.max || 6)) { if (interaction) return extInteraction.followUp({ content: 'Sorry, There is a game happening right now. Please try later.' }); else if (!interaction) return extMessage.reply({ content: 'Sorry, There is a game happening right now. Please try later.' }); } const x_emoji = options.buttons?.X?.emoji?.id || options.buttons?.X?.emoji || '❌'; const o_emoji = options.buttons?.O?.emoji?.id || options.buttons?.O?.emoji || '⭕'; const blank_emoji = options.buttons?.blank?.emoji || '➖'; if (options?.buttons?.blank?.style) options.buttons.blank.style = (0, misc_1.toButtonStyle)(options?.buttons?.blank?.style); if (options?.buttons?.X?.style) options.buttons.X.style = (0, misc_1.toButtonStyle)(options?.buttons?.X?.style); if (options?.buttons?.O?.style) options.buttons.O.style = (0, misc_1.toButtonStyle)(options?.buttons?.O?.style); const emptyStyle = options.buttons?.blank?.style || discord_js_1.ButtonStyle.Secondary; const XStyle = options.buttons?.X?.style || discord_js_1.ButtonStyle.Danger; const OStyle = options.buttons?.O?.style || discord_js_1.ButtonStyle.Success; if (interaction) { opponent = options.user || extInteraction.options.getUser('user'); if (!opponent) return ai(message, { max: options?.max || 6, blank_emoji: blank_emoji, x_emoji: x_emoji, o_emoji: o_emoji, x_style: XStyle, o_style: OStyle, emptyStyle: emptyStyle, embed: options.embed, buttons: options.buttons, type: options.type }); if (opponent.bot) return extInteraction.followUp({ content: 'You cannot play with bots!', ephemeral: true }); if (opponent.id == message.user.id) return extInteraction.followUp({ content: 'You cannot play with yourself!', ephemeral: true }); } else if (!interaction) { opponent = extMessage.mentions.users.first(); if (!opponent) return ai(message, { max: options?.max || 6, blank_emoji, x_emoji, o_emoji, x_style: XStyle, o_style: OStyle, emptyStyle, embed: options.embed, buttons: options.buttons, type: options.type }); if (opponent.bot) return extMessage.reply({ content: "You can't play with bots!" }); if (opponent.id === message.member.user.id) return extMessage.reply({ content: 'You cannot play with yourself!' }); } const requestEmbed = new discord_js_1.EmbedBuilder() .setTitle(options?.embed?.request?.title || `Tictactoe with ${opponent.username}`) .setDescription(options?.embed?.request?.description || 'Waiting for the opponent to accept/deny') .setAuthor(options?.embed?.request?.author || { name: message.member.user.username, iconURL: message.member.user.displayAvatarURL({ forceStatic: false }) }) .setColor(options.embed?.request?.color || (0, misc_1.toRgb)('#406DBC')) .setFooter(options.embed?.request?.footer ? options.embed?.request?.footer : { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }); if (options?.embed?.request?.fields) requestEmbed.setFields(options.embed?.request?.fields); if (options?.embed?.request?.author) requestEmbed.setAuthor(options.embed?.request?.author); if (options?.embed?.request?.image) requestEmbed.setImage(options.embed?.request?.image); if (options?.embed?.request?.thumbnail) requestEmbed.setThumbnail(options.embed?.request?.thumbnail); if (options?.embed?.request?.timestamp) requestEmbed.setTimestamp(options.embed?.request?.timestamp); if (options?.embed?.request?.title) requestEmbed.setTitle(options.embed?.request?.title); if (options?.embed?.request?.url) requestEmbed.setURL(options.embed?.request?.url); const accept = new discord_js_1.ButtonBuilder() .setLabel('Accept') .setStyle(discord_js_1.ButtonStyle.Success) .setCustomId('accept-ttt'); const deny = new discord_js_1.ButtonBuilder() .setLabel('Deny') .setStyle(discord_js_1.ButtonStyle.Danger) .setCustomId('deny-ttt'); const row = new discord_js_1.ActionRowBuilder().addComponents([ accept, deny ]); let m; if (interaction) { m = await extInteraction.followUp({ content: `<@${opponent.id}>, You got a tictactoe request from ${message.member.user.username}`, embeds: [requestEmbed], components: [row] }); } else if (!interaction) { m = await extMessage.reply({ content: `<@${opponent.id}>, You got a tictactoe request from ${message.member.user.username}`, embeds: [requestEmbed], components: [row] }); } limiter[id].limit += 1; const collector = m.createMessageComponentCollector({ componentType: discord_js_1.ComponentType.Button, time: (0, misc_1.ms)('30s') }); collector.on('collect', async (button) => { if (button.user.id !== opponent.id) { await button.reply({ content: `Only <@!${opponent.id}> can use these buttons!`, ephemeral: true }); return; } if (button.customId == 'deny-ttt') { await button.deferUpdate(); collector.stop('decline'); } else if (button.customId == 'accept-ttt') { await button.deferUpdate(); collector.stop(); const players = [message.member.user.id, opponent.id].sort(() => Math.random() > 0.5 ? 1 : -1); const gameEmbed = new discord_js_1.EmbedBuilder() .setTitle(options.embed?.game?.title || `${message.member.user.username} VS ${opponent.username}`) .setAuthor(options.embed?.game?.author || { name: message.member.user.username, iconURL: message.member.user.displayAvatarURL({ forceStatic: false }) }) .setColor(options.embed?.game?.color || (0, misc_1.toRgb)('#406DBC')) .setFooter(options.embed?.game?.footer ? options.embed?.game?.footer : { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }); if (options?.embed?.game?.fields) gameEmbed.setFields(options.embed?.game?.fields); if (options?.embed?.game?.author) gameEmbed.setAuthor(options.embed?.game?.author); if (options?.embed?.game?.image) gameEmbed.setImage(options.embed?.game?.image); if (options?.embed?.game?.thumbnail) gameEmbed.setThumbnail(options.embed?.game?.thumbnail); if (options?.embed?.game?.timestamp) gameEmbed.setTimestamp(options.embed?.game?.timestamp); if (options?.embed?.game?.url) gameEmbed.setURL(options.embed?.game?.url); const msg = await button.message.edit({ embeds: [ gameEmbed.setDescription(`Waiting for Input | <@!${players[0]}>, Your Emoji: ${client.emojis.cache.get(o_emoji) || '⭕'}`) ] }); const Game = { user: 0, userid: '', board: Array(9).fill({ style: emptyStyle, emoji: blank_emoji, disabled: false }) }; await tictactoeEngine(msg, { blank_emoji: blank_emoji }); async function tictactoeEngine(m, styles = {}) { const { blank_emoji } = styles; Game.userid = players[Game.user]; const won = { O: false, X: false }; function checkWin(emoji) { return combinations.some((combination) => { return combination.every((index) => { return Game.board[index].emoji == emoji; }); }); } function isDraw() { return [...Game.board].every((cell) => { return cell.emoji == x_emoji || cell.emoji == o_emoji; }); } const a1 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[0].style) .setEmoji(Game.board[0].emoji) .setCustomId('0') .setDisabled(Game.board[0].disabled); const a2 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[1].style) .setEmoji(Game.board[1].emoji) .setCustomId('1') .setDisabled(Game.board[1].disabled); const a3 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[2].style) .setEmoji(Game.board[2].emoji) .setCustomId('2') .setDisabled(Game.board[2].disabled); const b1 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[3].style) .setEmoji(Game.board[3].emoji) .setCustomId('3') .setDisabled(Game.board[3].disabled); const b2 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[4].style) .setEmoji(Game.board[4].emoji) .setCustomId('4') .setDisabled(Game.board[4].disabled); const b3 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[5].style) .setEmoji(Game.board[5].emoji) .setCustomId('5') .setDisabled(Game.board[5].disabled); const c1 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[6].style) .setEmoji(Game.board[6].emoji) .setCustomId('6') .setDisabled(Game.board[6].disabled); const c2 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[7].style) .setEmoji(Game.board[7].emoji) .setCustomId('7') .setDisabled(Game.board[7].disabled); const c3 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[8].style) .setEmoji(Game.board[8].emoji) .setCustomId('8') .setDisabled(Game.board[8].disabled); const a = new discord_js_1.ActionRowBuilder().addComponents([ a1, a2, a3 ]); const b = new discord_js_1.ActionRowBuilder().addComponents([ b1, b2, b3 ]); const c = new discord_js_1.ActionRowBuilder().addComponents([ c1, c2, c3 ]); const buttons = [a, b, c]; const winEmbed = new discord_js_1.EmbedBuilder() .setTitle(options.embed?.win?.title || `${message.member.user.username} VS ${opponent.username}`) .setColor(options.embed?.win?.color || `DarkGreen`) .setFooter(options.embed?.win?.footer ? options.embed?.win?.footer : { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }); if (options?.embed?.win?.fields) winEmbed.setFields(options.embed?.win?.fields); if (options?.embed?.win?.author) winEmbed.setAuthor(options.embed?.win?.author); if (options?.embed?.win?.image) winEmbed.setImage(options.embed?.win?.image); if (options?.embed?.win?.thumbnail) winEmbed.setThumbnail(options.embed?.win?.thumbnail); if (options?.embed?.win?.timestamp) winEmbed.setTimestamp(options.embed?.win?.timestamp); if (options?.embed?.win?.url) winEmbed.setURL(options.embed?.win?.url); if (checkWin(o_emoji)) won['O'] = true; if (checkWin(x_emoji)) won['X'] = true; if (won['O'] == true) { limiter[id].limit -= 1; if (limiter[id].limit < 0) limiter[id].limit = 0; const winner = await client.users .fetch(players[Game.user === 0 ? 1 : 0]) .catch(console.error); resolve(winner); if (!options.type || options.type === 'Button') return m .edit({ content: `<@${players[Game.user === 0 ? 1 : 0]}> (${client.emojis.cache.get(o_emoji) || '⭕'}) won`, components: (0, misc_1.disableButtons)(buttons), embeds: [ winEmbed .setAuthor(options.embed?.win?.author || { name: winner.username, iconURL: winner.displayAvatarURL({ forceStatic: false }) }) .setDescription(`<@!${players[Game.user === 0 ? 1 : 0]}> (${client.emojis.cache.get(o_emoji) || '⭕'}) won, That was a nice game.`) ] }) .then((m) => { m.react(client.emojis.cache.get(o_emoji) || '⭕'); }); else if (options?.type === 'Embed') return m .edit({ content: `<@${players[Game.user === 0 ? 1 : 0]}> (${client.emojis.cache.get(o_emoji) || '⭕'}) won`, embeds: [ winEmbed .setAuthor(options.embed?.win?.author || { name: winner.username, iconURL: winner.displayAvatarURL({ forceStatic: false }) }) .setDescription(`<@!${players[Game.user === 0 ? 1 : 0]}> (${client.emojis.cache.get(o_emoji) || '⭕'}) won.. That was a nice game.\n` + `\`\`\`\n${Game.board[0].emoji} | ${Game.board[1].emoji} | ${Game.board[2].emoji}\n${Game.board[3].emoji} | ${Game.board[4].emoji} | ${Game.board[5].emoji}\n${Game.board[6].emoji} | ${Game.board[7].emoji} | ${Game.board[8].emoji}\n\`\`\`` .replaceAll(blank_emoji, '➖') .replaceAll(o_emoji, '⭕') .replaceAll(x_emoji, '❌')) ], components: [] }) .then((m) => { m.react(client.emojis.cache.get(o_emoji) || '⭕'); }); } else if (won['X'] == true) { limiter[id].limit -= 1; if (limiter[id].limit < 0) limiter[id].limit = 0; const winner = await client.users .fetch(players[Game.user === 0 ? 1 : 0]) .catch(console.error); resolve(winner); if (!options.type || options.type === 'Button') return m .edit({ content: `<@${players[Game.user === 0 ? 1 : 0]}> (${client.emojis.cache.get(x_emoji) || '❌'}) won`, components: (0, misc_1.disableButtons)(buttons), embeds: [ winEmbed .setAuthor(options.embed?.win?.author || { name: winner.username, iconURL: winner.displayAvatarURL({ forceStatic: false }) }) .setDescription(`<@!${players[Game.user === 0 ? 1 : 0]}> (${client.emojis.cache.get(x_emoji) || '❌'}) won, That was a nice game.`) ] }) .then((m) => { m.react(client.emojis.cache.get(x_emoji) || '❌'); }); else if (options?.type === 'Embed') return m .edit({ content: `<@${players[Game.user === 0 ? 1 : 0]}> (${client.emojis.cache.get(o_emoji) || '❌'}) won`, embeds: [ winEmbed .setAuthor(options.embed?.win?.author || { name: winner.username, iconURL: winner.displayAvatarURL({ forceStatic: false }) }) .setDescription(`<@!${players[Game.user === 0 ? 1 : 0]}> (${client.emojis.cache.get(x_emoji) || '❌'}) won.. That was a nice game.\n` + `\`\`\`\n${Game.board[0].emoji} | ${Game.board[1].emoji} | ${Game.board[2].emoji}\n${Game.board[3].emoji} | ${Game.board[4].emoji} | ${Game.board[5].emoji}\n${Game.board[6].emoji} | ${Game.board[7].emoji} | ${Game.board[8].emoji}\n\`\`\`` .replaceAll(blank_emoji, '➖') .replaceAll(o_emoji, '⭕') .replaceAll(x_emoji, '❌')) ], components: [] }) .then((m) => { m.react(client.emojis.cache.get(x_emoji) || '❌'); }); } if (isDraw()) { limiter[id].limit -= 1; if (limiter[id].limit < 0) limiter[id].limit = 0; const drawEmbed = new discord_js_1.EmbedBuilder() .setTitle(options.embed?.draw?.title || `${message.member.user.username} VS ${opponent.username}`) .setColor(options.embed?.draw?.color || 'Grey') .setFooter(options.embed?.draw?.footer ? options.embed?.draw?.footer : { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }); if (options?.embed?.draw?.fields) drawEmbed.setFields(options.embed?.draw?.fields); if (options?.embed?.draw?.author) drawEmbed.setAuthor(options.embed?.draw?.author); if (options?.embed?.draw?.image) drawEmbed.setImage(options.embed?.draw?.image); if (options?.embed?.draw?.thumbnail) drawEmbed.setThumbnail(options.embed?.draw?.thumbnail); if (options?.embed?.draw?.timestamp) drawEmbed.setTimestamp(options.embed?.draw?.timestamp); if (options?.embed?.draw?.url) drawEmbed.setURL(options.embed?.draw?.url); if (!options.type || options.type === 'Button') return m .edit({ content: 'Its a Tie!', embeds: [ drawEmbed.setDescription(`You have tied. Play again to see who wins.`) ], components: buttons }) .then((m) => { m.react(blank_emoji); }); else return m .edit({ content: 'Its a Tie !', embeds: [ drawEmbed.setDescription(`You have tied. Play again to see who wins.\n` + `\`\`\`\n${Game.board[0].emoji} | ${Game.board[1].emoji} | ${Game.board[2].emoji}\n${Game.board[3].emoji} | ${Game.board[4].emoji} | ${Game.board[5].emoji}\n${Game.board[6].emoji} | ${Game.board[7].emoji} | ${Game.board[8].emoji}\n\`\`\`` .replaceAll(blank_emoji, '➖') .replaceAll(o_emoji, '⭕') .replaceAll(x_emoji, '❌')) ], components: [] }) .then((m) => { m.react(blank_emoji); }) .catch(() => { }); } const play = await client.users.fetch(players[Game.user]); m.edit({ content: `<@${Game.userid}>`, embeds: [ gameEmbed .setAuthor(options.embed?.game?.author || { name: play.username, iconURL: play.displayAvatarURL({ forceStatic: false }) }) .setDescription(`Waiting for Input | <@!${Game.userid}> | Your Emoji: ${Game.user == 0 ? `${client.emojis.cache.get(o_emoji) || '⭕'}` : `${client.emojis.cache.get(x_emoji) || '❌'}`}`) ], components: [a, b, c] }); const collector = m.createMessageComponentCollector({ componentType: discord_js_1.ComponentType.Button, max: 1, time: (0, misc_1.ms)('30s') }); collector.on('collect', async (b) => { if (b.user.id !== Game.userid && b.user.id === message.member.user.id) { b.reply({ content: `It's <@!${opponent.id}>'s' turn!`, ephemeral: true }); } else if (b.user.id !== Game.userid && b.user.id === opponent.id) { b.reply({ content: `It's <@!${message.member.user.id}>'s' turn!`, ephemeral: true }); } else if (b.user.id !== Game.userid && b.user.id !== opponent.id && b.user.id !== message.member.user.id) { b.reply({ content: `You cannot play this game!`, ephemeral: true }); } else if (b.user.id === Game.userid && (b.user.id === opponent.id || b.user.id === message.member.user.id) && Game.board[Number(b.customId)].emoji === x_emoji) { b.reply({ content: `That position is pre-occupied by ${client.emojis.cache.get(x_emoji) || '❌'}!`, ephemeral: true }); } else if (b.user.id === Game.userid && (b.user.id === opponent.id || b.user.id === message.member.user.id) && Game.board[Number(b.customId)].emoji === o_emoji) { b.reply({ content: `That position is pre-occupied by ${client.emojis.cache.get(o_emoji) || '⭕'}!`, ephemeral: true }); } else { await b.deferUpdate(); if (Game.user == 0) { Game.user = 1; Game.board[Number(b.customId)] = { style: OStyle, emoji: o_emoji, disabled: true }; } else { Game.user = 0; Game.board[Number(b.customId)] = { style: XStyle, emoji: x_emoji, disabled: true }; } } await tictactoeEngine(m, { blank_emoji: blank_emoji }); }); collector.on('end', (collected, reason) => { limiter[id].limit -= 1; if (limiter[id].limit < 0) limiter[id].limit = 0; const timeoutEmbed = new discord_js_1.EmbedBuilder() .setTitle(options.embed?.timeout?.title || 'Game Timed Out!') .setColor(options.embed?.timeout?.color || 'Red') .setDescription(options.embed?.timeout?.description || 'The opponent didnt respond in time (30s)') .setFooter(options.embed?.timeout?.footer ? options.embed?.timeout?.footer : { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }); if (options?.embed?.timeout?.fields) timeoutEmbed.setFields(options.embed?.timeout?.fields); if (options?.embed?.timeout?.author) timeoutEmbed.setAuthor(options.embed?.timeout?.author); if (options?.embed?.timeout?.image) timeoutEmbed.setImage(options.embed?.timeout?.image); if (options?.embed?.timeout?.thumbnail) timeoutEmbed.setThumbnail(options.embed?.timeout?.thumbnail); if (options?.embed?.timeout?.timestamp) timeoutEmbed.setTimestamp(options.embed?.timeout?.timestamp); if (options?.embed?.timeout?.url) timeoutEmbed.setURL(options.embed?.timeout?.url); if (collected.size === 0 && reason == 'idle') if (!options.type || options.type === 'Button') m.edit({ content: `<@!${Game.userid}> didn't react in time! (30s)`, embeds: [timeoutEmbed], components: (0, misc_1.disableButtons)(buttons) }); else m.edit({ content: `The opponent didnt respond in time (30s)`, embeds: [ timeoutEmbed.setDescription(`<@!${Game.userid}> didn't react in time! (30s)\n` + `\`\`\`\n${Game.board[0].emoji} | ${Game.board[1].emoji} | ${Game.board[2].emoji}\n${Game.board[3].emoji} | ${Game.board[4].emoji} | ${Game.board[5].emoji}\n${Game.board[6].emoji} | ${Game.board[7].emoji} | ${Game.board[8].emoji}\n\`\`\`` .replaceAll(blank_emoji, '➖') .replaceAll(o_emoji, '⭕') .replaceAll(x_emoji, '❌')) ], components: [] }); }); } } }); collector.on('end', (_collected, reason) => { limiter[id].limit -= 1; if (limiter[id].limit < 0) limiter[id].limit = 0; if (reason == 'time') { const timeoutEmbed = new discord_js_1.EmbedBuilder() .setTitle(options.embed?.timeout?.title || 'Game Timed Out!') .setColor(options.embed?.timeout?.color || 'Red') .setDescription(options.embed?.timeout?.description || 'The opponent didnt respond in time (30s)') .setFooter(options.embed?.timeout?.footer ? options.embed?.timeout?.footer : { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }); if (options?.embed?.timeout?.fields) timeoutEmbed.setFields(options.embed?.timeout?.fields); if (options?.embed?.timeout?.author) timeoutEmbed.setAuthor(options.embed?.timeout?.author); if (options?.embed?.timeout?.image) timeoutEmbed.setImage(options.embed?.timeout?.image); if (options?.embed?.timeout?.thumbnail) timeoutEmbed.setThumbnail(options.embed?.timeout?.thumbnail); if (options?.embed?.timeout?.timestamp) timeoutEmbed.setTimestamp(options.embed?.timeout?.timestamp); if (options?.embed?.timeout?.url) timeoutEmbed.setURL(options.embed?.timeout?.url); m.edit({ content: `<@${opponent.id}> did not accept in time!`, embeds: [timeoutEmbed], components: [] }); } else if (reason == 'decline') { const declineEmbed = new discord_js_1.EmbedBuilder() .setColor(options.embed?.decline?.color || 'Red') .setFooter(options.embed?.decline?.footer ? options.embed?.decline?.footer : { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }) .setTitle(options.embed?.decline?.title || 'Game Declined!') .setDescription(options.embed?.decline?.description || `${opponent.username} has declined your game request!`); if (options?.embed?.decline?.fields) declineEmbed.setFields(options.embed?.decline?.fields); if (options?.embed?.decline?.author) declineEmbed.setAuthor(options.embed?.decline?.author); if (options?.embed?.decline?.image) declineEmbed.setImage(options.embed?.decline?.image); if (options?.embed?.decline?.thumbnail) declineEmbed.setThumbnail(options.embed?.decline?.thumbnail); if (options?.embed?.decline?.timestamp) declineEmbed.setTimestamp(options.embed?.decline?.timestamp); if (options?.embed?.decline?.url) declineEmbed.setURL(options.embed?.decline?.url); m.edit({ embeds: [declineEmbed], components: [] }); } }); } catch (err) { { if (options?.strict) throw new error_1.SimplyError({ function: 'tictactoe', title: 'An Error occured when running the function ', tip: err.stack }); else console.log(`SimplyError - tictactoe | Error: ${err.stack}`); } } }); } exports.tictactoe = tictactoe; async function ai(msgOrint, options = { max: 5 }) { const { client } = msgOrint; let board = ['', '', '', '', '', '', '', '', '']; let message; let interaction; if (msgOrint.commandId) { interaction = msgOrint; } const extInteraction = msgOrint; const extMessage = msgOrint; let id = limiter.findIndex((a) => a.guild == msgOrint.guild.id); if (!limiter[id] || !limiter[id].guild) { limiter.push({ guild: msgOrint.guild.id, limit: 0 }); id = limiter.findIndex((a) => a.guild == msgOrint.guild.id); } if (limiter[id].limit >= (options?.max || 6)) { if (interaction) return extInteraction.followUp({ content: 'Sorry, There is a game happening right now. Please try later.' }); else if (!interaction) return extMessage.reply({ content: 'Sorry, There is a game happening right now. Please try later.' }); } const Game = { board: Array(9).fill({ style: options.emptyStyle, emoji: options.blank_emoji, disabled: false }) }; const opponent = msgOrint.client.user; const gameEmbed = new discord_js_1.EmbedBuilder() .setTitle(options.embed?.game?.title || `${msgOrint.member.user.username} VS ${opponent.username}`) .setAuthor(options.embed?.game?.author || { name: msgOrint.member.user.username, iconURL: msgOrint.member.user.displayAvatarURL({ forceStatic: false }) }) .setDescription(`Waiting for Input | <@!${msgOrint.member.user.id}> | Your Emoji: ${client.emojis.cache.get(options.x_emoji) || '❌'}`) .setColor(options.embed?.game?.color || (0, misc_1.toRgb)('#406DBC')) .setFooter(options.embed?.game?.footer ? options.embed?.game?.footer : { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }); if (options?.embed?.game?.fields) gameEmbed.setFields(options.embed?.game?.fields); if (options?.embed?.game?.author) gameEmbed.setAuthor(options.embed?.game?.author); if (options?.embed?.game?.image) gameEmbed.setImage(options.embed?.game?.image); if (options?.embed?.game?.thumbnail) gameEmbed.setThumbnail(options.embed?.game?.thumbnail); if (options?.embed?.game?.timestamp) gameEmbed.setTimestamp(options.embed?.game?.timestamp); if (options?.embed?.game?.url) gameEmbed.setURL(options.embed?.game?.url); const buttons = update(); if (interaction) { message = await extInteraction.followUp({ embeds: [gameEmbed], components: buttons }); } else if (!interaction) { message = await extMessage.reply({ embeds: [gameEmbed], components: buttons }); } limiter[id].limit += 1; function checkWin(emoji) { return combinations.some((combination) => { return combination.every((index) => { return Game.board[index].emoji == emoji; }); }); } function isDraw() { return [...Game.board].every((cell) => { return cell.emoji == options.x_emoji || cell.emoji == options.o_emoji; }); } function update() { const a1 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[0].style) .setEmoji(Game.board[0].emoji) .setCustomId('0') .setDisabled(Game.board[0].disabled); const a2 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[1].style) .setEmoji(Game.board[1].emoji) .setCustomId('1') .setDisabled(Game.board[1].disabled); const a3 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[2].style) .setEmoji(Game.board[2].emoji) .setCustomId('2') .setDisabled(Game.board[2].disabled); const b1 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[3].style) .setEmoji(Game.board[3].emoji) .setCustomId('3') .setDisabled(Game.board[3].disabled); const b2 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[4].style) .setEmoji(Game.board[4].emoji) .setCustomId('4') .setDisabled(Game.board[4].disabled); const b3 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[5].style) .setEmoji(Game.board[5].emoji) .setCustomId('5') .setDisabled(Game.board[5].disabled); const c1 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[6].style) .setEmoji(Game.board[6].emoji) .setCustomId('6') .setDisabled(Game.board[6].disabled); const c2 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[7].style) .setEmoji(Game.board[7].emoji) .setCustomId('7') .setDisabled(Game.board[7].disabled); const c3 = new discord_js_1.ButtonBuilder() .setStyle(Game.board[8].style) .setEmoji(Game.board[8].emoji) .setCustomId('8') .setDisabled(Game.board[8].disabled); const a = new discord_js_1.ActionRowBuilder().addComponents([a1, a2, a3]); const b = new discord_js_1.ActionRowBuilder().addComponents([b1, b2, b3]); const c = new discord_js_1.ActionRowBuilder().addComponents([c1, c2, c3]); return [a, b, c]; } const filter = (interaction) => { if (interaction.user.id === msgOrint.member.user.id) return true; interaction.reply({ content: `You cannot play this game!`, ephemeral: true }); return; }; const aiCollector = message.createMessageComponentCollector({ componentType: discord_js_1.ComponentType.Button, idle: 30000, filter: filter }); let aiTurn = false; aiCollector.on('collect', async (button) => { if (isDraw() || checkWin(options.x_emoji) || checkWin(options.o_emoji)) aiCollector.stop(); if (!button.deferred) await button.deferUpdate(); if (aiTurn) { await button.followUp({ content: `It's <@!${opponent.id}>'s turn!`, ephemeral: true }); return; } else if (Game.board[Number(button.customId)].emoji === options.x_emoji) { await button.followUp({ content: `That position is pre-occupied by ${client.emojis.cache.get(options.x_emoji) || '❌'}!`, ephemeral: true }); return; } else if (Game.board[Number(button.customId)].emoji === options.o_emoji) { await button.followUp({ content: `That position is pre-occupied by ${client.emojis.cache.get(options.o_emoji) || '⭕'}!`, ephemeral: true }); return; } aiTurn = true; board[Number(button.customId)] = 'x'; const buttonInitial = update(); await message.edit({ components: buttonInitial }); for (let i = 0; i < board.length; i++) { const elem = board[i]; if (elem == 'x') { Game.board[i] = { style: options.x_style, emoji: options.x_emoji, disabled: true }; } } const buttonUpdateX = update(); if (!isDraw() && !checkWin(options.x_emoji) && !checkWin(options.o_emoji)) message.edit({ embeds: [ gameEmbed .setDescription(`AI is Thinking.. | <@!${opponent.id}> | Your Emoji: ${client.emojis.cache.get(options.o_emoji) || '⭕'}`) .setColor(`DarkerGrey`) ], components: buttonUpdateX }); if (!isDraw() && !checkWin(options.x_emoji) && !checkWin(options.o_emoji)) { aiCollector.resetTimer(); board = await aiEngine(board); } for (let i = 0; i