Skip to content

Commit d46ad1e

Browse files
Fix bugs with /blackjack and make deck shuffling more efficient
1 parent 1667024 commit d46ad1e

2 files changed

Lines changed: 48 additions & 28 deletions

File tree

src/main/java/technobot/commands/casino/BlackjackCommand.java

Lines changed: 39 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
import technobot.commands.Category;
1313
import technobot.commands.Command;
1414
import technobot.data.GuildData;
15-
import technobot.data.cache.Economy;
1615
import technobot.handlers.economy.EconomyHandler;
1716
import technobot.listeners.ButtonListener;
1817
import technobot.util.embeds.EmbedColor;
1918
import technobot.util.embeds.EmbedUtils;
2019
import technobot.util.enums.Cards;
2120

2221
import java.util.*;
22+
import java.util.concurrent.TimeUnit;
2323

2424
/**
2525
* Command that plays a game of blackjack.
@@ -30,25 +30,28 @@ public class BlackjackCommand extends Command {
3030

3131
public static final String CARDBACK_EMOJI = "<:cardback:992575657320140801>";
3232
public static final Map<String, Blackjack> games = new HashMap<>();
33-
public static final Stack<Cards> deck = new Stack<>();
33+
public static final Map<String, Stack<Cards>> decks = new HashMap<>();
3434

3535
public BlackjackCommand(TechnoBot bot) {
3636
super(bot);
3737
this.name = "blackjack";
3838
this.description = "Play a game of blackjack.";
3939
this.category = Category.CASINO;
4040
this.args.add(new OptionData(OptionType.INTEGER, "bet", "The amount you want to wager", true).setMinValue(1));
41-
42-
// Setup deck of cards
43-
for (Cards card : Cards.values()) {
44-
deck.push(card);
45-
}
4641
}
4742

4843
@Override
4944
public void execute(SlashCommandInteractionEvent event) {
50-
// Charge player for bet
45+
// Check if game already exists
5146
User user = event.getUser();
47+
String userID = user.getId();
48+
if (games.containsKey(userID)) {
49+
String text = "You are already playing a blackjack game!";
50+
event.replyEmbeds(EmbedUtils.createError(text)).setEphemeral(true).queue();
51+
return;
52+
}
53+
54+
// Charge player for bet
5255
long bet = event.getOption("bet").getAsLong();
5356
EconomyHandler economyHandler = GuildData.get(event.getGuild()).economyHandler;
5457
long balance = economyHandler.getBalance(user.getIdLong());
@@ -60,39 +63,54 @@ public void execute(SlashCommandInteractionEvent event) {
6063
}
6164
economyHandler.removeMoney(user.getIdLong(), bet);
6265

63-
// Shuffle deck
64-
Stack<Cards> shuffledDeck = (Stack<Cards>) deck.clone();
65-
Collections.shuffle(shuffledDeck);
66+
// Create and shuffle draw deck
67+
Stack<Cards> deck = decks.get(userID);
68+
if (deck == null || deck.size() <= 15) {
69+
deck = new Stack<>();
70+
for (Cards card : Cards.values()) {
71+
deck.push(card);
72+
}
73+
Collections.shuffle(deck);
74+
decks.put(userID, deck);
75+
}
6676

6777
// Create new blackjack game
68-
Cards dealerCard = shuffledDeck.pop();
78+
Cards dealerCard = deck.pop();
6979
List<Cards> playerHand = new ArrayList<>();
70-
playerHand.add(shuffledDeck.pop());
71-
playerHand.add(shuffledDeck.pop());
72-
games.put(user.getId(), new Blackjack(shuffledDeck, dealerCard, playerHand));
80+
playerHand.add(deck.pop());
81+
playerHand.add(deck.pop());
82+
games.put(user.getId(), new Blackjack(userID, dealerCard, playerHand));
7383

7484
// Send embed with buttons
7585
int score = calculateValue(playerHand);
7686
MessageEmbed embed = getEmbed(user, score).build();
7787
String uuid = user.getId() + ":" + UUID.randomUUID();
7888
List<Button> buttons = List.of(Button.primary("blackjack:hit:"+uuid+":"+bet, "Hit"), Button.secondary("blackjack:stand:"+uuid+":"+bet, "Stand"));
7989
ButtonListener.buttons.put(uuid, buttons);
80-
event.replyEmbeds(embed).addActionRow(buttons).queue(interactionHook -> ButtonListener.disableButtons(uuid, interactionHook));
90+
event.replyEmbeds(embed).addActionRow(buttons).queue(interactionHook -> {
91+
// Delete all game data if no response for 3 min
92+
ButtonListener.disableButtons(uuid, interactionHook);
93+
ButtonListener.executor.schedule(() -> {
94+
decks.remove(userID);
95+
games.remove(userID);
96+
}, 3, TimeUnit.MINUTES);
97+
});
8198
}
8299

83100
/**
84101
* Stores and represents a blackjack game.
85102
*
86-
* @param deck the shuffled deck of cards to draw from.
87103
* @param dealerCard the card that the dealer has revealed.
88104
* @param playerHand List of cards that the player has.
89105
*/
90-
public record Blackjack(Stack<Cards> deck, Cards dealerCard, List<Cards> playerHand) {
106+
public record Blackjack(String userID, Cards dealerCard, List<Cards> playerHand) {
91107

92108
/**
93109
* Draws a card from the deck and adds it to the player's hand.
94110
*/
95-
public void hit() { playerHand.add(deck.pop()); }
111+
public void hit() {
112+
playerHand.add(decks.get(userID).pop());
113+
}
96114
}
97115

98116
/**
@@ -150,7 +168,7 @@ private static List<Cards> revealDealerHand(Blackjack game, int playerScore) {
150168
dealerHand.add(game.dealerCard());
151169
int dealerScore = game.dealerCard().value;
152170
do {
153-
Cards card = game.deck().pop();
171+
Cards card = decks.get(game.userID()).pop();
154172
dealerScore += card.value;
155173
dealerHand.add(card);
156174
} while (dealerScore < playerScore && dealerScore < 17);
@@ -178,7 +196,7 @@ public static MessageEmbed hit(Guild guild, User user, long bet, String uuid) {
178196
if (score >= 21) {
179197
if (score > 21) {
180198
// Player busted
181-
List<Cards> dealerHand = List.of(game.dealerCard(), game.deck().pop());
199+
List<Cards> dealerHand = List.of(game.dealerCard(), decks.get(game.userID()).pop());
182200
int dealerScore = calculateValue(dealerHand);
183201
embed = getResultEmbed(user, dealerHand, score, dealerScore);
184202
embed.setDescription("Result: Bust " + currency + " -" + bet);

src/main/java/technobot/listeners/ButtonListener.java

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public class ButtonListener extends ListenerAdapter {
3232

3333
public static final int MINUTES_TO_DISABLE = 3;
3434

35-
public static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(10);
35+
public static final ScheduledExecutorService executor = Executors.newScheduledThreadPool(20);
3636
public static final Map<String, List<MessageEmbed>> menus = new HashMap<>();
3737
public static final Map<String, List<Button>> buttons = new HashMap<>();
3838

@@ -118,10 +118,11 @@ private static List<Button> getResetButtons(String uuid, String systemName) {
118118
public static void disableButtons(String uuid, InteractionHook hook) {
119119
Runnable task = () -> {
120120
List<Button> actionRow = ButtonListener.buttons.get(uuid);
121-
for (int i = 0; i < actionRow.size(); i++) {
122-
actionRow.set(i, actionRow.get(i).asDisabled());
121+
List<Button> newActionRow = new ArrayList<>();
122+
for (Button button : actionRow) {
123+
newActionRow.add(button.asDisabled());
123124
}
124-
hook.editOriginalComponents(ActionRow.of(actionRow)).queue(null, new ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE));
125+
hook.editOriginalComponents(ActionRow.of(newActionRow)).queue(null, new ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE));
125126
ButtonListener.buttons.remove(uuid);
126127
ButtonListener.menus.remove(uuid);
127128
};
@@ -137,10 +138,11 @@ public static void disableButtons(String uuid, InteractionHook hook) {
137138
public static void disableButtons(String uuid, Message hook) {
138139
Runnable task = () -> {
139140
List<Button> actionRow = ButtonListener.buttons.get(uuid);
140-
for (int i = 0; i < actionRow.size(); i++) {
141-
actionRow.set(i, actionRow.get(i).asDisabled());
141+
List<Button> newActionRow = new ArrayList<>();
142+
for (Button button : actionRow) {
143+
newActionRow.add(button.asDisabled());
142144
}
143-
hook.editMessageComponents(ActionRow.of(actionRow)).queue(null, new ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE));
145+
hook.editMessageComponents(ActionRow.of(newActionRow)).queue(null, new ErrorHandler().ignore(ErrorResponse.UNKNOWN_MESSAGE));
144146
ButtonListener.buttons.remove(uuid);
145147
ButtonListener.menus.remove(uuid);
146148
};

0 commit comments

Comments
 (0)