Last active
March 23, 2023 10:49
-
-
Save giorgi-o/9c7eede3b5c72c8b9f071b6dc8c8cd3c to your computer and use it in GitHub Desktop.
Discord Tic Tac Toe using Buttons (Components)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Tic Tac Toe using Discord's new components! | |
* https://reddit.com/r/discordapp/comments/nn733r | |
* | |
* Discord released their "components" feature yesterday, | |
* and I thought I might as well create something to | |
* try and learn how to use them, so here we go. | |
* This version doesn't even check for a winner lol. | |
* | |
* NOTE: As of 28/05, THIS WILL NOT WORK on the | |
* stable version of discord.js. You need to install | |
* monbrey's fork of discord.js, specifically the | |
* #message-components branch: | |
* | |
* npm install monbrey/discord.js#message-components | |
* | |
* A pull request has been submitted and the devs are | |
* going over it, but even then it will only be in | |
* master. For it to arrive in stable (the version | |
* you get using "npm install discord.js"), you | |
* need to wait until v13 is published, which won't | |
* happen for a long time, and this code will only | |
* work if they don't change anything between now | |
* and then, which is highly unlikely. | |
* Anyways, enjoy :) | |
* | |
* Made by u/giorgiocav123 | |
*/ | |
const Discord = require('discord.js'); | |
const client = new Discord.Client({intents: Discord.Intents.NON_PRIVILEGED}); | |
client.on("ready", async () => { | |
console.log(`Logged in as ${client.user.tag}!`); | |
for(const guild of client.guilds.cache.values()) | |
await guild.commands.create({ | |
name: "tictactoe", | |
description: "Play tic tac toe!" | |
}).catch(() => {}); | |
}); | |
/** @type interaction {Discord.CommandInteraction} */ | |
client.on("interaction", async interaction => { | |
if(interaction.isCommand() && interaction.commandName === "tictactoe") { | |
interaction.reply("Here we go!", { | |
components: [ | |
{type: 1, components: [ | |
{type: 2, label: "_", style: 2, custom_id: "ttt11"}, | |
{type: 2, label: "_", style: 2, custom_id: "ttt12"}, | |
{type: 2, label: "_", style: 2, custom_id: "ttt13"}, | |
]}, | |
{type: 1, components: [ | |
{type: 2, label: "_", style: 2, custom_id: "ttt21"}, | |
{type: 2, label: "_", style: 2, custom_id: "ttt22"}, | |
{type: 2, label: "_", style: 2, custom_id: "ttt23"}, | |
]}, | |
{type: 1, components: [ | |
{type: 2, label: "_", style: 2, custom_id: "ttt31"}, | |
{type: 2, label: "_", style: 2, custom_id: "ttt32"}, | |
{type: 2, label: "_", style: 2, custom_id: "ttt33"}, | |
]}, | |
] | |
}); | |
} else if(interaction.isMessageComponent() && interaction.customID.startsWith("ttt")) { | |
await updateGrid(interaction); | |
} | |
}); | |
/** | |
* | |
* @param {Discord.MessageComponentInteraction} interaction | |
*/ | |
async function updateGrid(interaction) { | |
/** @type {Discord.Message} message */ | |
const message = interaction.message; | |
let xs = 0, os = 0; | |
for(let actionRow of message.components) { | |
for(let button of actionRow.components) { | |
if(button.label === 'X') xs++; | |
else if(button.label === 'O') os++; | |
} | |
} | |
const xs_turn = xs <= os; | |
const i = parseInt(interaction.customID[3]), | |
j = parseInt(interaction.customID[4]); | |
const buttonPressed = message.components[i-1].components[j-1]; | |
if(buttonPressed.label !== '_') | |
return await interaction.reply("Someone already played there!", {ephemeral: true}); | |
buttonPressed.label = xs_turn ? 'X' : 'O'; | |
buttonPressed.style = xs_turn ? "SUCCESS" : "DANGER"; | |
const styleToNumber = style => style === "SECONDARY" ? 2 : style === "SUCCESS" ? 3 : 4; | |
const components = []; | |
for(let actionRow of message.components) { | |
components.push({type: 1, components: []}); | |
for (let button of actionRow.components) { | |
components[components.length - 1].components.push({type: 2, label: button.label, style: styleToNumber(button.style), custom_id: button.customID}); | |
} | |
} | |
await message.edit({components: components}); | |
await interaction.deferUpdate(); | |
} | |
client.login("almost leaked my token there whoops"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is hella nice!