mirror of
https://github.com/arthur-pbty/xiao.git
synced 2026-06-03 15:07:42 +02:00
Bingo Command
This commit is contained in:
@@ -224,7 +224,7 @@ in the appropriate channel's topic to use it.
|
||||
|
||||
## Commands
|
||||
|
||||
Total: 456
|
||||
Total: 457
|
||||
|
||||
### Utility:
|
||||
|
||||
@@ -505,6 +505,7 @@ Total: 456
|
||||
|
||||
* **balloon-pop:** Don't let yourself be the last one to pump the balloon before it pops!
|
||||
* **battle:** Engage in a turn-based battle against another user or the AI.
|
||||
* **bingo:** Play bingo with up to 99 other users.
|
||||
* **connect-four:** Play a game of Connect Four with another user.
|
||||
* **dots-and-boxes:** Play a game of Dots and Boxes with another user.
|
||||
* **emoji-emoji-revolution:** Can you type arrow emoji faster than anyone else has ever typed them before?
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"B": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
|
||||
"I": [16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
|
||||
"N": [31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45],
|
||||
"G": [46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60],
|
||||
"O": [61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75]
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
const Command = require('../../structures/Command');
|
||||
const Collection = require('@discordjs/collection');
|
||||
const { stripIndents } = require('common-tags');
|
||||
const { randomRange } = require('../../util/Util');
|
||||
const { SUCCESS_EMOJI_ID } = process.env;
|
||||
const nums = require('../../assets/json/bingo');
|
||||
const rows = Object.keys(nums);
|
||||
|
||||
module.exports = class BingoCommand extends Command {
|
||||
constructor(client) {
|
||||
super(client, {
|
||||
name: 'bingo',
|
||||
group: 'games-mp',
|
||||
memberName: 'bingo',
|
||||
description: 'Play bingo with up to 99 other users.',
|
||||
guildOnly: true,
|
||||
args: [
|
||||
{
|
||||
key: 'playersCount',
|
||||
prompt: 'How many players are you expecting to have?',
|
||||
type: 'integer',
|
||||
min: 1,
|
||||
max: 100
|
||||
}
|
||||
]
|
||||
});
|
||||
}
|
||||
|
||||
async run(msg, { playersCount }) {
|
||||
const current = this.client.games.get(msg.channel.id);
|
||||
if (current) return msg.reply(`Please wait until the current game of \`${current.name}\` is finished.`);
|
||||
this.client.games.set(msg.channel.id, { name: this.name });
|
||||
try {
|
||||
const awaitedPlayers = await this.awaitPlayers(msg, playersCount);
|
||||
if (!awaitedPlayers) {
|
||||
this.client.games.delete(msg.channel.id);
|
||||
return msg.say('Game could not be started...');
|
||||
}
|
||||
const players = new Collection();
|
||||
for (const player of awaitedPlayers) {
|
||||
players.set(player, {
|
||||
board: this.generateBoard(),
|
||||
id: player,
|
||||
user: await this.client.users.fetch(player)
|
||||
});
|
||||
}
|
||||
let winner = null;
|
||||
const called = ['FR'];
|
||||
while (!winner) {
|
||||
const picked = randomRange(1, 75);
|
||||
called.push(picked);
|
||||
for (const player of players.values()) {
|
||||
try {
|
||||
await player.user.send(this.generateBoardDisplay(player.board, called));
|
||||
} catch {
|
||||
await msg.say(`${player.user}, I couldn't send your board! Turn on DMs!`);
|
||||
}
|
||||
}
|
||||
await msg.say(stripIndents`
|
||||
**${this.findRowValue(picked)}${picked}**!
|
||||
|
||||
Check your DMs for your board. If you have bingo, type \`bingo\`!
|
||||
_Next number will be called in 10 seconds._
|
||||
`);
|
||||
const filter = res => {
|
||||
if (!players.has(res.author.id)) return false;
|
||||
if (res.content.toLowerCase() !== 'bingo') return false;
|
||||
if (!this.checkBingo(players.get(res.author.id).board), called) {
|
||||
msg.say(`${res.author}, you don't have bingo, liar.`).catch(() => null);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
const bingo = await msg.channel.awaitMessages(filter, { max: 1, time: 10000 });
|
||||
if (!bingo) continue;
|
||||
winner = bingo.first().author;
|
||||
}
|
||||
this.client.games.delete(msg.channel.id);
|
||||
return msg.say(`Congrats, ${winner.user}!`);
|
||||
} catch (err) {
|
||||
this.client.games.delete(msg.channel.id);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
async awaitPlayers(msg, players) {
|
||||
await msg.say(`You will need at least 1 more player (at max ${players - 1}). To join, type \`join game\`.`);
|
||||
const joined = [];
|
||||
joined.push(msg.author.id);
|
||||
const filter = res => {
|
||||
if (res.author.bot) return false;
|
||||
if (joined.includes(res.author.id)) return false;
|
||||
if (res.content.toLowerCase() !== 'join game') return false;
|
||||
joined.push(res.author.id);
|
||||
res.react(SUCCESS_EMOJI_ID || '✅').catch(() => null);
|
||||
return true;
|
||||
};
|
||||
const verify = await msg.channel.awaitMessages(filter, { max: players - 1, time: 30000 });
|
||||
verify.set(msg.id, msg);
|
||||
if (verify.size < 1) return false;
|
||||
return verify.map(player => player.author.id);
|
||||
}
|
||||
|
||||
generateBoard() {
|
||||
const result = [];
|
||||
for (const [rowID, values] of Object.entries(nums)) {
|
||||
const nums = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
const valid = values.filter(value => !nums.includes(value));
|
||||
nums.push(valid[Math.floor(Math.random() * valid.length)]);
|
||||
}
|
||||
const sorted = nums.sort((a, b) => a - b);
|
||||
if (rowID === 'N') sorted[2] = 'FR';
|
||||
result.push(sorted);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
generateBoardDisplay(board, called) {
|
||||
const mapped = board.map((values, i) => {
|
||||
const row = rows[i];
|
||||
const mapVal = values.map(value => {
|
||||
if (called.includes(value) || value === 'FR') return 'XX';
|
||||
return value.toString().padStart(2, '0');
|
||||
}).join(' | ')
|
||||
return `${row} | ${mapVal}`;
|
||||
}).join('\n\n');
|
||||
return stripIndents`
|
||||
\`\`\`
|
||||
${mapped}
|
||||
\`\`\`
|
||||
`;
|
||||
}
|
||||
|
||||
findRowValue(num) {
|
||||
if (nums.B.includes(num)) return 'B';
|
||||
if (nums.I.includes(num)) return 'I';
|
||||
if (nums.N.includes(num)) return 'N';
|
||||
if (nums.G.includes(num)) return 'G';
|
||||
if (nums.O.includes(num)) return 'O';
|
||||
return null;
|
||||
}
|
||||
|
||||
checkLine(called, a, b, c, d, e) {
|
||||
return called.includes(a)
|
||||
&& called.includes(b)
|
||||
&& called.includes(c)
|
||||
&& called.includes(d)
|
||||
&& called.includes(e);
|
||||
}
|
||||
|
||||
checkBingo(bd, ca) {
|
||||
for (let r = 0; r < rows.length; r++) {
|
||||
if (this.checkLine(ca, bd[r][0], bd[r][1], bd[r][2], bd[r][3], bd[r][4])) return true;
|
||||
}
|
||||
for (let c = 0; c < rows.length; c++) {
|
||||
if (this.checkLine(ca, bd[0][c], bd[1][c], bd[2][c], bd[3][c], bd[4][c])) return true;
|
||||
}
|
||||
if (this.checkLine(ca, bd[0][0], bd[1][1], bd[2][2], bd[3][3], bd[4][4])) return true;
|
||||
if (this.checkLine(ca, bd[4][0], bd[3][1], bd[2][2], bd[1][3], bd[0][4])) return true;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -60,7 +60,7 @@ module.exports = class PokerCommand extends Command {
|
||||
money: 5000,
|
||||
id: player,
|
||||
hand: [],
|
||||
user: this.client.users.cache.get(player),
|
||||
user: await this.client.users.fetch(player),
|
||||
currentBet: 0,
|
||||
hasGoneOnce: false,
|
||||
strikes: 0
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "xiao",
|
||||
"version": "116.1.7",
|
||||
"version": "116.2.0",
|
||||
"description": "Your personal server companion.",
|
||||
"main": "Xiao.js",
|
||||
"scripts": {
|
||||
|
||||
Reference in New Issue
Block a user