Bingo Command

This commit is contained in:
Dragon Fire
2020-06-06 17:26:03 -04:00
parent 7f5dbb68e0
commit dda985420d
5 changed files with 174 additions and 3 deletions
+2 -1
View File
@@ -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?
+7
View File
@@ -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]
}
+163
View File
@@ -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;
}
};
+1 -1
View File
@@ -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
View File
@@ -1,6 +1,6 @@
{
"name": "xiao",
"version": "116.1.7",
"version": "116.2.0",
"description": "Your personal server companion.",
"main": "Xiao.js",
"scripts": {