Create a player loop for a blackjack game

Hi everyone! I'm currently implementing a game of blackjack in my bot, using an embed and buttons for the game information and functions. It is two-player, with the command to start the game having an option to mention the other player, with player 1 being the command initiator. My issue is in how to make the game loop back and forth between both players then break when someone wins. The code specifically for the game itself is below:
if (interaction.customId === "accept") { // This is from an earlier collector which asks the target if they wish to play or not
await interaction.deferUpdate();
const reply = await interaction.editReply({
embeds: [blackjackEmbed],
components: [hitStand],
});

const hitStandFilter = (i) =>
(i.customId === "hit" || "stand") &&
(i.member.id === target.id || i.member.id == interaction.user);
const hitStandCollector = reply.createMessageComponentCollector(
{
componentType: ComponentType.Button,
filter: hitStandFilter,
max: 1,
time: 10000,
}
);

hitStandCollector.on("collect", async (interaction) => {
if (
interaction.customId === "hit" &&
currentPlayerIndex === 0
) {
let count1 = 0;
let count2 = 0;
count1 += hitCard(); // Function declared earlier, just randomly adds a number to simulate the "hit" in blackjack
currentPlayerIndex = 1 - currentPlayerIndex; // Declared earlier to be 0, flips between 0 and 1 to check whose turn it is
const newBlackjackEmbed = new EmbedBuilder()
.setTitle("Blackjack")
.setColor("Red")
.setDescription(
"`\`` _____\n|A . |\n| /.\\ |\n|(_._)|\n| | |\n|____Ɐ|\n`\``\nWelcome to blackjack. Press the buttons below to hit or stand."
)
.addFields(
{
name: "Player 1's count",
value: `${count1}`,
},
{ name: "Player 2's count", value: "0" },
{
name: "The current player is:",
value: `Player ${currentPlayerIndex}`,
}
);
await interaction.deferUpdate();
await interaction.editReply({
embeds: [newBlackjackEmbed],
});
return;
} else if ((interaction, customId === "stand")) {
await interaction.reply("test 2"); // Stand function is unimplemented
return;
}
});
return;
} else if (interaction.customId === "deny") {
await interaction.deferUpdate();
await interaction.editReply({
content: `You have declined the game.`,
embeds: [],
components: [],
});
return;
}
if (interaction.customId === "accept") { // This is from an earlier collector which asks the target if they wish to play or not
await interaction.deferUpdate();
const reply = await interaction.editReply({
embeds: [blackjackEmbed],
components: [hitStand],
});

const hitStandFilter = (i) =>
(i.customId === "hit" || "stand") &&
(i.member.id === target.id || i.member.id == interaction.user);
const hitStandCollector = reply.createMessageComponentCollector(
{
componentType: ComponentType.Button,
filter: hitStandFilter,
max: 1,
time: 10000,
}
);

hitStandCollector.on("collect", async (interaction) => {
if (
interaction.customId === "hit" &&
currentPlayerIndex === 0
) {
let count1 = 0;
let count2 = 0;
count1 += hitCard(); // Function declared earlier, just randomly adds a number to simulate the "hit" in blackjack
currentPlayerIndex = 1 - currentPlayerIndex; // Declared earlier to be 0, flips between 0 and 1 to check whose turn it is
const newBlackjackEmbed = new EmbedBuilder()
.setTitle("Blackjack")
.setColor("Red")
.setDescription(
"`\`` _____\n|A . |\n| /.\\ |\n|(_._)|\n| | |\n|____Ɐ|\n`\``\nWelcome to blackjack. Press the buttons below to hit or stand."
)
.addFields(
{
name: "Player 1's count",
value: `${count1}`,
},
{ name: "Player 2's count", value: "0" },
{
name: "The current player is:",
value: `Player ${currentPlayerIndex}`,
}
);
await interaction.deferUpdate();
await interaction.editReply({
embeds: [newBlackjackEmbed],
});
return;
} else if ((interaction, customId === "stand")) {
await interaction.reply("test 2"); // Stand function is unimplemented
return;
}
});
return;
} else if (interaction.customId === "deny") {
await interaction.deferUpdate();
await interaction.editReply({
content: `You have declined the game.`,
embeds: [],
components: [],
});
return;
}
My idea for a solution is to check the current player id to flip between whose turn it is, however the "hit" collector only collects once, if I try to "hit" a second time it simply gives "this interaction has failed." How would I be able to loop through the players until one wins, by maybe allowing the collector to always collect, similar to the behaviour of addEventListener in default JS for HTML elements?
3 Replies
d.js toolkit
d.js toolkit10mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
Val
Val10mo ago
Val
Val10mo ago
so the filter would look like this? it doesn't work for some reason it works for the first two turns, then when it's my turn again it gives an "interaction has failed" ohhh i see