v12 不会删除机器人的反应,但 v13 会删除机器人的反应 (discord.js)
v12 doesn't remove bot's react, but v13 remove bot's react (discord.js)
在命令从v12升级到v13的过程中,我发现命令删除了它自己创建的bot反应,而v12没有。
两个机器人都有管理员权限。
v12 来自 djs-games module, game connect four。我将 v12 改进为 v13
v12 :
const discord = require('discord.js')
class ConnectFour {
constructor() {
this.gameEmbed = null
}
startGame (msg) {
const challenger = msg.author;
const oppenent = msg.mentions.users.first();
if(!oppenent) return msg.channel.send(`**With whom do you wanna play Connect Four?**`)
const board = [
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
];
const renderBoard = (board) => {
let tempString = "";
for (const boardSection of board) {
tempString += `${boardSection.join("")}\n`;
}
tempString = tempString.concat("1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣");
return tempString;
}
const initialState = renderBoard(board);
const initial = new discord.MessageEmbed()
.setTitle(` ${msg.author.username} its your turn!`)
.setDescription(initialState)
.setFooter(`${challenger.username} vs ${oppenent.username}`)
msg.channel.send(initial).then(gameMessage => {
gameMessage.react("1️⃣")
gameMessage.react("2️⃣")
gameMessage.react("3️⃣")
gameMessage.react("4️⃣")
gameMessage.react("5️⃣")
gameMessage.react("6️⃣")
gameMessage.react("7️⃣")
const gameFilter = (reaction, user) => ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣"].includes(reaction.emoji.name) && (user.id === oppenent.id || user.id === challenger.id);
const gameCollector = gameMessage.createReactionCollector(gameFilter);
const gameData = [
{ member: challenger, playerColor: "" },
{ member: oppenent, playerColor: ""}
]
let player = 0;
const checkFour = (a, b, c, d) => (a === b) && (b === c) && (c === d) && (a !== "⚪");
const horizontalCheck = () => {
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 4; j++) {
if(checkFour(board[i][j], board[i][j + 1], board[i][j + 2], board[i][j + 3])) return [
board[i][j], board[i][j + 1], board[i][j + 2], board[i][j + 3]
];
}
}
}
const verticalCheck = () => {
for (let j = 0; j < 7; j++) {
for (let i = 0; i < 3; i++) {
if(checkFour(board[i][j], board[i + 1][j], board[i + 2][j], board[i + 3][j])) return [
board[i][j], board[i + 1][j], board[i + 2][j], board[i + 3][j]
]
}
}
}
const diagonal1 = () => {
for (let col = 0; col < 4; col++) {
for (let row = 0; row < 3; row++) {
if(checkFour(board[row][col], board[row + 1][col + 1], board[row + 2][col + 2], board[row + 3][col + 3])) return [
board[row][col], board[row + 1][col + 1], board[row + 2][col + 2], board[row + 3][col + 3]
]
}
}
}
const diagonal2 = () => {
for (let col = 0; col < 4; col++) {
for (let row = 5; row > 2; row--) {
if(checkFour(board[row][col], board[row - 1][col + 1], board[row - 2][col + 2], board[row - 3][col + 3])) return [
board[row][col], board[row - 1][col + 1], board[row - 2][col + 2], board[row - 3][col + 3]
]
}
}
}
const tieCheck = () => {
let count = 0;
for (const el of board) {
for (const string of el) {
if(string !== "⚪") count++;
}
}
if(count === 42) return true;
else return false;
}
const checks = [horizontalCheck, verticalCheck, diagonal1, diagonal2];
gameCollector.on("collect", (reaction, user) => {
reaction.message.reactions.cache.get(reaction.emoji.name).users.remove(user.id);
if(user.id === gameData[player].member.id) {
const openSpaces = [];
switch (reaction.emoji.name) {
case "1️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][0] === "⚪") openSpaces.push({ i, j: 0});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "2️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][1] === "⚪") openSpaces.push({ i, j: 1});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "3️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][2] === "⚪") openSpaces.push({ i, j: 2});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "4️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][3] === "⚪") openSpaces.push({ i, j: 3});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "5️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][4] === "⚪") openSpaces.push({ i, j: 4});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "6️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][5] === "⚪") openSpaces.push({ i, j: 5});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "7️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][6] === "⚪") openSpaces.push({ i, j: 6});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
}
if(tieCheck()) {
gameMessage.reactions.removeAll()
const TieEmbed = new discord.MessageEmbed()
.setTitle(`The game ended, it is Tie!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameCollector.stop("Tie Game")
return gameMessage.edit(TieEmbed)
}
for (const func of checks) {
const data = func();
if(data) {
gameMessage.reactions.removeAll()
const WinEmbed = new discord.MessageEmbed()
.setTitle(`${gameData[player].member.username} has won the game!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameCollector.stop(`${gameData[player].member.id} won`);
return gameMessage.edit(WinEmbed)
}
}
player = (player + 1) % 2;
const newEmbed = new discord.MessageEmbed()
.setTitle(`${gameData[player].playerColor} - ${gameData[player].member.username} its your turn!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameMessage.edit("", { embed: newEmbed});
}
})
})
}
}
module.exports = ConnectFour;
v13 :
const discord = require('discord.js')
class ConnectFour {
constructor() {
this.gameEmbed = null
}
startGame (msg) {
const challenger = msg.author;
const oppenent = msg.mentions.users.first();
if(!oppenent) return msg.channel.send(`**With whom do you wanna play Connect Four?**`)
const board = [
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
];
const renderBoard = (board) => {
let tempString = "";
for (const boardSection of board) {
tempString += `${boardSection.join("")}\n`;
}
tempString = tempString.concat("1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣");
return tempString;
}
const initialState = renderBoard(board);
const initial = new discord.MessageEmbed()
.setTitle(` ${msg.author.username} its your turn!`)
.setDescription(initialState)
.setFooter(`${challenger.username} vs ${oppenent.username}`)
msg.channel.send({embeds : [initial]}).then(gameMessage => {
gameMessage.react("1️⃣")
gameMessage.react("2️⃣")
gameMessage.react("3️⃣")
gameMessage.react("4️⃣")
gameMessage.react("5️⃣")
gameMessage.react("6️⃣")
gameMessage.react("7️⃣")
const gameFilter = (reaction, user) => ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣"].includes(reaction.emoji.name) && (user.id === oppenent.id || user.id === challenger.id);
const gameCollector = gameMessage.createReactionCollector(gameFilter);
const gameData = [
{ member: challenger, playerColor: "" },
{ member: oppenent, playerColor: ""}
]
let player = 0;
const checkFour = (a, b, c, d) => (a === b) && (b === c) && (c === d) && (a !== "⚪");
const horizontalCheck = () => {
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 4; j++) {
if(checkFour(board[i][j], board[i][j + 1], board[i][j + 2], board[i][j + 3])) return [
board[i][j], board[i][j + 1], board[i][j + 2], board[i][j + 3]
];
}
}
}
const verticalCheck = () => {
for (let j = 0; j < 7; j++) {
for (let i = 0; i < 3; i++) {
if(checkFour(board[i][j], board[i + 1][j], board[i + 2][j], board[i + 3][j])) return [
board[i][j], board[i + 1][j], board[i + 2][j], board[i + 3][j]
]
}
}
}
const diagonal1 = () => {
for (let col = 0; col < 4; col++) {
for (let row = 0; row < 3; row++) {
if(checkFour(board[row][col], board[row + 1][col + 1], board[row + 2][col + 2], board[row + 3][col + 3])) return [
board[row][col], board[row + 1][col + 1], board[row + 2][col + 2], board[row + 3][col + 3]
]
}
}
}
const diagonal2 = () => {
for (let col = 0; col < 4; col++) {
for (let row = 5; row > 2; row--) {
if(checkFour(board[row][col], board[row - 1][col + 1], board[row - 2][col + 2], board[row - 3][col + 3])) return [
board[row][col], board[row - 1][col + 1], board[row - 2][col + 2], board[row - 3][col + 3]
]
}
}
}
const tieCheck = () => {
let count = 0;
for (const el of board) {
for (const string of el) {
if(string !== "⚪") count++;
}
}
if(count === 42) return true;
else return false;
}
const checks = [horizontalCheck, verticalCheck, diagonal1, diagonal2];
gameCollector.on("collect", (reaction, user) => {
reaction.message.reactions.cache.get(reaction.emoji.name).users.remove(user.id);
if(user.id === gameData[player].member.id) {
const openSpaces = [];
switch (reaction.emoji.name) {
case "1️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][0] === "⚪") openSpaces.push({ i, j: 0});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "2️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][1] === "⚪") openSpaces.push({ i, j: 1});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "3️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][2] === "⚪") openSpaces.push({ i, j: 2});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "4️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][3] === "⚪") openSpaces.push({ i, j: 3});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "5️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][4] === "⚪") openSpaces.push({ i, j: 4});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "6️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][5] === "⚪") openSpaces.push({ i, j: 5});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "7️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][6] === "⚪") openSpaces.push({ i, j: 6});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
}
if(tieCheck()) {
gameMessage.reactions.removeAll()
const TieEmbed = new discord.MessageEmbed()
.setTitle(`The game ended, it is Tie!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameCollector.stop("Tie Game")
return gameMessage.edit({embeds : [TieEmbed]})
}
for (const func of checks) {
const data = func();
if(data) {
gameMessage.reactions.removeAll()
const WinEmbed = new discord.MessageEmbed()
.setTitle(`${gameData[player].member.username} has won the game!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameCollector.stop(`${gameData[player].member.id} won`);
return gameMessage.edit({embeds : [WinEmbed]})
}
}
player = (player + 1) % 2;
const newEmbed = new discord.MessageEmbed()
.setTitle(`${gameData[player].playerColor} - ${gameData[player].member.username} its your turn!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameMessage.edit({embed: [newEmbed]});
}
})
})
}
}
module.exports = ConnectFour;
输出:
我认为原因是:
reaction.message.reactions.cache.get(reaction.emoji.name).users.remove(user.id); //line 122
在 v13 中,机器人自动删除了它自己创建的反应。
我希望机器人不会那样自动删除,以便用户可以轻松交互。
如果有任何错误,请原谅我,因为我是这门编程语言的新手。
谢谢!
所以为了让它在 discord.js v13 上运行,我必须做一些事情。
要收集公会用户的反应,您需要 GUILD_MESSAGE_REACTIONS
意图。所以我将其添加到 client
的意图中。
const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_MESSAGE_REACTIONS"] });
接下来,他们更改了您为 Message.createReactionCollector()
指定过滤器的方式。所以我相应地更新了代码。
const gameCollector = gameMessage.createReactionCollector({ filter: gameFilter });
最后,要编辑带有嵌入的消息,您需要将 newEmbed
放在 属性 的数组中 embeds
放在 MessageEditOptions
的数组中。您在 embeds
末尾遗漏了“s”,这可能是一个错误,因为在其他任何地方您都正确地使用了它。
gameMessage.edit({embeds: [newEmbed]});
结果是一个运行良好的游戏:)
在命令从v12升级到v13的过程中,我发现命令删除了它自己创建的bot反应,而v12没有。
两个机器人都有管理员权限。 v12 来自 djs-games module, game connect four。我将 v12 改进为 v13
v12 :
const discord = require('discord.js')
class ConnectFour {
constructor() {
this.gameEmbed = null
}
startGame (msg) {
const challenger = msg.author;
const oppenent = msg.mentions.users.first();
if(!oppenent) return msg.channel.send(`**With whom do you wanna play Connect Four?**`)
const board = [
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
];
const renderBoard = (board) => {
let tempString = "";
for (const boardSection of board) {
tempString += `${boardSection.join("")}\n`;
}
tempString = tempString.concat("1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣");
return tempString;
}
const initialState = renderBoard(board);
const initial = new discord.MessageEmbed()
.setTitle(` ${msg.author.username} its your turn!`)
.setDescription(initialState)
.setFooter(`${challenger.username} vs ${oppenent.username}`)
msg.channel.send(initial).then(gameMessage => {
gameMessage.react("1️⃣")
gameMessage.react("2️⃣")
gameMessage.react("3️⃣")
gameMessage.react("4️⃣")
gameMessage.react("5️⃣")
gameMessage.react("6️⃣")
gameMessage.react("7️⃣")
const gameFilter = (reaction, user) => ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣"].includes(reaction.emoji.name) && (user.id === oppenent.id || user.id === challenger.id);
const gameCollector = gameMessage.createReactionCollector(gameFilter);
const gameData = [
{ member: challenger, playerColor: "" },
{ member: oppenent, playerColor: ""}
]
let player = 0;
const checkFour = (a, b, c, d) => (a === b) && (b === c) && (c === d) && (a !== "⚪");
const horizontalCheck = () => {
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 4; j++) {
if(checkFour(board[i][j], board[i][j + 1], board[i][j + 2], board[i][j + 3])) return [
board[i][j], board[i][j + 1], board[i][j + 2], board[i][j + 3]
];
}
}
}
const verticalCheck = () => {
for (let j = 0; j < 7; j++) {
for (let i = 0; i < 3; i++) {
if(checkFour(board[i][j], board[i + 1][j], board[i + 2][j], board[i + 3][j])) return [
board[i][j], board[i + 1][j], board[i + 2][j], board[i + 3][j]
]
}
}
}
const diagonal1 = () => {
for (let col = 0; col < 4; col++) {
for (let row = 0; row < 3; row++) {
if(checkFour(board[row][col], board[row + 1][col + 1], board[row + 2][col + 2], board[row + 3][col + 3])) return [
board[row][col], board[row + 1][col + 1], board[row + 2][col + 2], board[row + 3][col + 3]
]
}
}
}
const diagonal2 = () => {
for (let col = 0; col < 4; col++) {
for (let row = 5; row > 2; row--) {
if(checkFour(board[row][col], board[row - 1][col + 1], board[row - 2][col + 2], board[row - 3][col + 3])) return [
board[row][col], board[row - 1][col + 1], board[row - 2][col + 2], board[row - 3][col + 3]
]
}
}
}
const tieCheck = () => {
let count = 0;
for (const el of board) {
for (const string of el) {
if(string !== "⚪") count++;
}
}
if(count === 42) return true;
else return false;
}
const checks = [horizontalCheck, verticalCheck, diagonal1, diagonal2];
gameCollector.on("collect", (reaction, user) => {
reaction.message.reactions.cache.get(reaction.emoji.name).users.remove(user.id);
if(user.id === gameData[player].member.id) {
const openSpaces = [];
switch (reaction.emoji.name) {
case "1️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][0] === "⚪") openSpaces.push({ i, j: 0});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "2️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][1] === "⚪") openSpaces.push({ i, j: 1});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "3️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][2] === "⚪") openSpaces.push({ i, j: 2});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "4️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][3] === "⚪") openSpaces.push({ i, j: 3});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "5️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][4] === "⚪") openSpaces.push({ i, j: 4});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "6️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][5] === "⚪") openSpaces.push({ i, j: 5});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "7️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][6] === "⚪") openSpaces.push({ i, j: 6});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
}
if(tieCheck()) {
gameMessage.reactions.removeAll()
const TieEmbed = new discord.MessageEmbed()
.setTitle(`The game ended, it is Tie!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameCollector.stop("Tie Game")
return gameMessage.edit(TieEmbed)
}
for (const func of checks) {
const data = func();
if(data) {
gameMessage.reactions.removeAll()
const WinEmbed = new discord.MessageEmbed()
.setTitle(`${gameData[player].member.username} has won the game!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameCollector.stop(`${gameData[player].member.id} won`);
return gameMessage.edit(WinEmbed)
}
}
player = (player + 1) % 2;
const newEmbed = new discord.MessageEmbed()
.setTitle(`${gameData[player].playerColor} - ${gameData[player].member.username} its your turn!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameMessage.edit("", { embed: newEmbed});
}
})
})
}
}
module.exports = ConnectFour;
v13 :
const discord = require('discord.js')
class ConnectFour {
constructor() {
this.gameEmbed = null
}
startGame (msg) {
const challenger = msg.author;
const oppenent = msg.mentions.users.first();
if(!oppenent) return msg.channel.send(`**With whom do you wanna play Connect Four?**`)
const board = [
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
["⚪", "⚪", "⚪", "⚪", "⚪", "⚪", "⚪"],
];
const renderBoard = (board) => {
let tempString = "";
for (const boardSection of board) {
tempString += `${boardSection.join("")}\n`;
}
tempString = tempString.concat("1️⃣2️⃣3️⃣4️⃣5️⃣6️⃣7️⃣");
return tempString;
}
const initialState = renderBoard(board);
const initial = new discord.MessageEmbed()
.setTitle(` ${msg.author.username} its your turn!`)
.setDescription(initialState)
.setFooter(`${challenger.username} vs ${oppenent.username}`)
msg.channel.send({embeds : [initial]}).then(gameMessage => {
gameMessage.react("1️⃣")
gameMessage.react("2️⃣")
gameMessage.react("3️⃣")
gameMessage.react("4️⃣")
gameMessage.react("5️⃣")
gameMessage.react("6️⃣")
gameMessage.react("7️⃣")
const gameFilter = (reaction, user) => ["1️⃣", "2️⃣", "3️⃣", "4️⃣", "5️⃣", "6️⃣", "7️⃣"].includes(reaction.emoji.name) && (user.id === oppenent.id || user.id === challenger.id);
const gameCollector = gameMessage.createReactionCollector(gameFilter);
const gameData = [
{ member: challenger, playerColor: "" },
{ member: oppenent, playerColor: ""}
]
let player = 0;
const checkFour = (a, b, c, d) => (a === b) && (b === c) && (c === d) && (a !== "⚪");
const horizontalCheck = () => {
for (let i = 0; i < 6; i++) {
for (let j = 0; j < 4; j++) {
if(checkFour(board[i][j], board[i][j + 1], board[i][j + 2], board[i][j + 3])) return [
board[i][j], board[i][j + 1], board[i][j + 2], board[i][j + 3]
];
}
}
}
const verticalCheck = () => {
for (let j = 0; j < 7; j++) {
for (let i = 0; i < 3; i++) {
if(checkFour(board[i][j], board[i + 1][j], board[i + 2][j], board[i + 3][j])) return [
board[i][j], board[i + 1][j], board[i + 2][j], board[i + 3][j]
]
}
}
}
const diagonal1 = () => {
for (let col = 0; col < 4; col++) {
for (let row = 0; row < 3; row++) {
if(checkFour(board[row][col], board[row + 1][col + 1], board[row + 2][col + 2], board[row + 3][col + 3])) return [
board[row][col], board[row + 1][col + 1], board[row + 2][col + 2], board[row + 3][col + 3]
]
}
}
}
const diagonal2 = () => {
for (let col = 0; col < 4; col++) {
for (let row = 5; row > 2; row--) {
if(checkFour(board[row][col], board[row - 1][col + 1], board[row - 2][col + 2], board[row - 3][col + 3])) return [
board[row][col], board[row - 1][col + 1], board[row - 2][col + 2], board[row - 3][col + 3]
]
}
}
}
const tieCheck = () => {
let count = 0;
for (const el of board) {
for (const string of el) {
if(string !== "⚪") count++;
}
}
if(count === 42) return true;
else return false;
}
const checks = [horizontalCheck, verticalCheck, diagonal1, diagonal2];
gameCollector.on("collect", (reaction, user) => {
reaction.message.reactions.cache.get(reaction.emoji.name).users.remove(user.id);
if(user.id === gameData[player].member.id) {
const openSpaces = [];
switch (reaction.emoji.name) {
case "1️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][0] === "⚪") openSpaces.push({ i, j: 0});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "2️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][1] === "⚪") openSpaces.push({ i, j: 1});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "3️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][2] === "⚪") openSpaces.push({ i, j: 2});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "4️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][3] === "⚪") openSpaces.push({ i, j: 3});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "5️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][4] === "⚪") openSpaces.push({ i, j: 4});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "6️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][5] === "⚪") openSpaces.push({ i, j: 5});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
case "7️⃣":
for (let i = 5; i > -1 ; i--) {
if(board[i][6] === "⚪") openSpaces.push({ i, j: 6});
}
if(openSpaces.length == 0) return msg.channel.send(`**${gameData[player].member}, that column is already full. Choose another one**`).then(msg1 => msg1.delete({timeout: 10000}))
else board[openSpaces[0].i][openSpaces[0].j] = gameData[player].playerColor;
break;
}
if(tieCheck()) {
gameMessage.reactions.removeAll()
const TieEmbed = new discord.MessageEmbed()
.setTitle(`The game ended, it is Tie!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameCollector.stop("Tie Game")
return gameMessage.edit({embeds : [TieEmbed]})
}
for (const func of checks) {
const data = func();
if(data) {
gameMessage.reactions.removeAll()
const WinEmbed = new discord.MessageEmbed()
.setTitle(`${gameData[player].member.username} has won the game!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameCollector.stop(`${gameData[player].member.id} won`);
return gameMessage.edit({embeds : [WinEmbed]})
}
}
player = (player + 1) % 2;
const newEmbed = new discord.MessageEmbed()
.setTitle(`${gameData[player].playerColor} - ${gameData[player].member.username} its your turn!`)
.setDescription(renderBoard(board))
.setFooter(`${challenger.username} vs ${oppenent.username}`)
gameMessage.edit({embed: [newEmbed]});
}
})
})
}
}
module.exports = ConnectFour;
输出:
我认为原因是:
reaction.message.reactions.cache.get(reaction.emoji.name).users.remove(user.id); //line 122
在 v13 中,机器人自动删除了它自己创建的反应。 我希望机器人不会那样自动删除,以便用户可以轻松交互。
如果有任何错误,请原谅我,因为我是这门编程语言的新手。
谢谢!
所以为了让它在 discord.js v13 上运行,我必须做一些事情。
要收集公会用户的反应,您需要 GUILD_MESSAGE_REACTIONS
意图。所以我将其添加到 client
的意图中。
const client = new Discord.Client({ intents: ["GUILDS", "GUILD_MESSAGES", "GUILD_MESSAGE_REACTIONS"] });
接下来,他们更改了您为 Message.createReactionCollector()
指定过滤器的方式。所以我相应地更新了代码。
const gameCollector = gameMessage.createReactionCollector({ filter: gameFilter });
最后,要编辑带有嵌入的消息,您需要将 newEmbed
放在 属性 的数组中 embeds
放在 MessageEditOptions
的数组中。您在 embeds
末尾遗漏了“s”,这可能是一个错误,因为在其他任何地方您都正确地使用了它。
gameMessage.edit({embeds: [newEmbed]});
结果是一个运行良好的游戏:)