mirror of
https://github.com/arthur-pbty/xiao.git
synced 2026-06-04 15:56:52 +02:00
157 lines
4.5 KiB
JavaScript
157 lines
4.5 KiB
JavaScript
const Command = require('../../structures/Command');
|
|
const { stripIndents } = require('common-tags');
|
|
const { shuffle, verify } = require('../../util/Util');
|
|
const suits = ['♣', '♥', '♦', '♠'];
|
|
const faces = ['Jack', 'Queen', 'King'];
|
|
|
|
module.exports = class BlackjackCommand extends Command {
|
|
constructor(client) {
|
|
super(client, {
|
|
name: 'blackjack',
|
|
aliases: ['twenty-one', '21', 'bj'],
|
|
group: 'games',
|
|
memberName: 'blackjack',
|
|
description: 'Play a game of blackjack.',
|
|
args: [
|
|
{
|
|
key: 'deckCount',
|
|
label: 'amount of decks',
|
|
prompt: 'How many decks do you want to use?',
|
|
type: 'integer',
|
|
default: 1,
|
|
max: 8,
|
|
min: 1
|
|
}
|
|
]
|
|
});
|
|
|
|
this.decks = new Map();
|
|
}
|
|
|
|
async run(msg, { deckCount }) {
|
|
if (this.decks.has(msg.channel.id)) return msg.reply('Only one game may be occurring per channel.');
|
|
try {
|
|
this.decks.set(msg.channel.id, this.generateDeck(deckCount));
|
|
const dealerHand = [];
|
|
this.draw(msg.channel, dealerHand);
|
|
this.draw(msg.channel, dealerHand);
|
|
const playerHand = [];
|
|
this.draw(msg.channel, playerHand);
|
|
this.draw(msg.channel, playerHand);
|
|
const dealerInitialTotal = this.calculate(dealerHand);
|
|
const playerInitialTotal = this.calculate(playerHand);
|
|
if (dealerInitialTotal === 21 && playerInitialTotal === 21) {
|
|
this.decks.delete(msg.channel.id);
|
|
return msg.say('Well, both of you just hit blackjack. Right away. Rigged.');
|
|
} else if (dealerInitialTotal === 21) {
|
|
this.decks.delete(msg.channel.id);
|
|
return msg.say('Ouch, the dealer hit blackjack right away! Try again!');
|
|
} else if (playerInitialTotal === 21) {
|
|
this.decks.delete(msg.channel.id);
|
|
return msg.say('Wow, you hit blackjack right away! Lucky you!');
|
|
}
|
|
let playerTurn = true;
|
|
let win = false;
|
|
let reason;
|
|
while (!win) {
|
|
if (playerTurn) {
|
|
await msg.say(stripIndents`
|
|
**First Dealer Card:** ${dealerHand[0].display}
|
|
|
|
**You (${this.calculate(playerHand)}):**
|
|
${playerHand.map(card => card.display).join('\n')}
|
|
|
|
_Hit?_
|
|
`);
|
|
const hit = await verify(msg.channel, msg.author);
|
|
if (hit) {
|
|
const card = this.draw(msg.channel, playerHand);
|
|
const total = this.calculate(playerHand);
|
|
if (total > 21) {
|
|
reason = `You drew ${card.display}, total of ${total}! Bust`;
|
|
break;
|
|
} else if (total === 21) {
|
|
reason = `You drew ${card.display} and hit 21`;
|
|
win = true;
|
|
}
|
|
} else {
|
|
const dealerTotal = this.calculate(dealerHand);
|
|
await msg.say(`Second dealer card is ${dealerHand[1].display}, total of ${dealerTotal}.`);
|
|
playerTurn = false;
|
|
}
|
|
} else {
|
|
const inital = this.calculate(dealerHand);
|
|
let card;
|
|
if (inital < 17) card = this.draw(msg.channel, dealerHand);
|
|
const total = this.calculate(dealerHand);
|
|
if (total > 21) {
|
|
reason = `Dealer drew ${card.display}, total of ${total}! Dealer bust`;
|
|
win = true;
|
|
} else if (total >= 17) {
|
|
const playerTotal = this.calculate(playerHand);
|
|
if (total === playerTotal) {
|
|
reason = `${card ? `Dealer drew ${card.display}, making it ` : ''}${playerTotal}-${total}`;
|
|
break;
|
|
} else if (total > playerTotal) {
|
|
reason = `${card ? `Dealer drew ${card.display}, making it ` : ''}${playerTotal}-**${total}**`;
|
|
break;
|
|
} else {
|
|
reason = `${card ? `Dealer drew ${card.display}, making it ` : ''}**${playerTotal}**-${total}`;
|
|
win = true;
|
|
}
|
|
} else {
|
|
await msg.say(`Dealer drew ${card.display}, total of ${total}.`);
|
|
}
|
|
}
|
|
}
|
|
this.decks.delete(msg.channel.id);
|
|
if (win) return msg.say(`${reason}! You won!`);
|
|
return msg.say(`${reason}! Too bad.`);
|
|
} catch (err) {
|
|
this.decks.delete(msg.channel.id);
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
generateDeck(deckCount) {
|
|
const deck = [];
|
|
for (let i = 0; i < deckCount; i++) {
|
|
for (const suit of suits) {
|
|
deck.push({
|
|
value: 11,
|
|
display: `${suit} Ace`
|
|
});
|
|
for (let j = 2; j <= 10; j++) {
|
|
deck.push({
|
|
value: j,
|
|
display: `${suit} ${j}`
|
|
});
|
|
}
|
|
for (const face of faces) {
|
|
deck.push({
|
|
value: 10,
|
|
display: `${suit} ${face}`
|
|
});
|
|
}
|
|
}
|
|
}
|
|
return shuffle(deck);
|
|
}
|
|
|
|
draw(channel, hand) {
|
|
const deck = this.decks.get(channel.id);
|
|
const card = deck[0];
|
|
deck.shift();
|
|
hand.push(card);
|
|
return card;
|
|
}
|
|
|
|
calculate(hand) {
|
|
return hand.sort((a, b) => a.value - b.value).reduce((a, b) => {
|
|
let { value } = b;
|
|
if (value === 11 && a + value > 21) value = 1;
|
|
return a + value;
|
|
}, 0);
|
|
}
|
|
};
|