Skip to content

Commit

Permalink
Merge pull request #49 from Mazawrath/beanLotteryFix
Browse files Browse the repository at this point in the history
Bean lottery fix
  • Loading branch information
Mazawrath authored Feb 2, 2019
2 parents 7e56cf5 + a363ae4 commit 631f242
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 99 deletions.
2 changes: 2 additions & 0 deletions src/main/java/com/mazawrath/beanbot/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class Main {
private static DiscordApi api;

public static void main(String[] args) {

Sentry.init();
System.setProperty("log4j2.loggerContextFactory", "org.apache.logging.log4j.core.impl.Log4jContextFactory");

Expand Down Expand Up @@ -62,6 +63,7 @@ public static void main(String[] args) {
cmdHandler.registerCommand(new ServerInfoCommand());
cmdHandler.registerCommand(new ReactCommand(points));
cmdHandler.registerCommand(new SourceCommand());
cmdHandler.registerCommand(new MinesweeperCommand(points));
// beanCoin
cmdHandler.registerCommand(new BeanBalanceCommand(points));
cmdHandler.registerCommand(new BeanFreeCommand(points));
Expand Down
130 changes: 130 additions & 0 deletions src/main/java/com/mazawrath/beanbot/commands/MinesweeperCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package com.mazawrath.beanbot.commands;

import com.mazawrath.beanbot.utilities.Points;
import com.mazawrath.beanbot.utilities.SentryLog;
import de.btobastian.sdcf4j.Command;
import de.btobastian.sdcf4j.CommandExecutor;
import io.sentry.Sentry;
import org.apache.commons.lang3.StringUtils;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.ServerTextChannel;
import org.javacord.api.entity.message.Message;
import org.javacord.api.entity.server.Server;
import org.javacord.api.entity.user.User;

import java.util.Arrays;
import java.util.Random;

public class MinesweeperCommand implements CommandExecutor {
private Points points;

public MinesweeperCommand(Points points) {
this.points = points;
}

@Command(
aliases = {"minesweeper"},
usage = "minesweeper [size] [mines]",
description = "Creates a minesweeper field with custom size options.",
privateMessages = false
)

public void onCommand(String[] args, DiscordApi api, ServerTextChannel serverTextChannel, User author, Server server, Message message) {
SentryLog.addContext(args, author, server);

int size;
int mines;

if (args.length >= 2) {
if (StringUtils.isNumeric(args[0]) && StringUtils.isNumeric(args[1])) {
size = Integer.parseInt(args[0]);
mines = Integer.parseInt(args[1]);
} else {
serverTextChannel.sendMessage("Invalid numbers.");
return;
}
} else {
size = 10;
mines = size * size / 6;
}

if (points.removePoints(author.getIdAsString(), api.getYourself().getIdAsString(), server.getIdAsString(), Points.COMMAND_COST)) {
serverTextChannel.sendMessage(new MinesweeperField(ensureInRange(size, 1,14), ensureInRange(mines, 1, size*size)).toDiscordString());
}

Sentry.clearContext();
}

private int ensureInRange(int value, int min, int max) {
return (value < min) ? min : ((value > max) ? max : value);
}

private static class MinesweeperField {
private final char[][] field;

public MinesweeperField(int size, int mines) {
if (size * size < mines) {
throw new IllegalArgumentException("too many mines");
}
this.field = new char[size][size];
for (char[] row : field) {
Arrays.fill(row, ' ');
}
placeMines(mines);
calculateFields();
}

private void placeMines(int mines) {
Random random = new Random();
for (int i = 0; i < mines; ) {
int x = random.nextInt(field.length);
int y = random.nextInt(field.length);
if (field[y][x] == ' ') {
field[y][x] = 'B';
i++;
}
}
}

private void calculateFields() {
for (int y = 0; y < field.length; y++) {
for (int x = 0; x < field[y].length; x++) {
if (field[y][x] == ' ') field[y][x] = (char) ('0' + countMinesAround(x, y));
}
}
}

private int countMinesAround(int xCenter, int yCenter) {
int numMines = 0;
for (int y = yCenter - 1; y <= yCenter + 1; y++) {
if (y < 0 || y == field.length) continue;
for (int x = xCenter - 1; x <= xCenter + 1; x++) {
if (x < 0 || x == field[y].length) continue;
if (field[y][x] == 'B') numMines++;
}
}
return numMines;
}

public String toString() {
StringBuilder builder = new StringBuilder();
for (char[] row : field) {
builder.append(new String(row)).append("\n");
}
return builder.toString();
}

public String toDiscordString() {
StringBuilder builder = new StringBuilder();
for (char[] row : field) {
for (char c : row) {
builder.append("||");
builder.append((c == 'B') ? "\uD83D\uDCA3" : c + "\u20E3");
builder.append("||");
}
builder.append("\n");
}
return builder.toString();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,19 @@ public void onCommand(String[] args, DiscordApi api, ServerTextChannel serverTex

private String getRecentChangeLog() {
return "**New beanBOT update released.**\n" +
"Release can be found on https://github.com/Mazawrath/beanBOT/releases/tag/v3.3.0\n" +
"Detailed changelog can be found on https://github.com/Mazawrath/beanBOT/compare/v3.2.0...v3.3.0\n" +
"Release can be found on https://github.com/Mazawrath/beanBOT/releases/tag/v3.4.0\n" +
"Detailed changelog can be found on https://github.com/Mazawrath/beanBOT/compare/v3.3.0...v3.4.0\n" +
"\n" +
"**v3.3.0**\n" +
"**v3.4.0**\n" +
"**New**\n" +
"\t- Added `.adminlookupuser`.\n" +
"\t- Added Sentry to track and manage run time errors in production.\n" +
// "**Changes**\n" +
// "\t- Disabled `.beanlottery draw`." +
"\t- Added `.minesweeper`.\n" +
"**Changes**\n" +
"\t- Set limit to how many lottery tickets can be bought in a single drawing to 200.\n" +
"\t- Set max lottery number to be drawn from 40 to 20.\n" +
"\t- Removed minimum amount required for automatic bean lottery drawings.\n" +
"\t- Bean coin from `.beanbet` will only go to the bot when the bet loses.\n" +
"**Bug Fixes**\n" +
"\t- Fixed an issue where users could buy less than one bean lottery ticket.\n" +
"\t- Fixed an issue with mentioning users with nicknames.";
"\t- Fixed outdated info with `.beanlottery draw`.\n" +
"\t- Fixed an issue with integer checks with `.beanlottery`.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public void onCommand(String[] args, DiscordApi api, ServerTextChannel serverTex
if (winningPoints.compareTo(BigDecimal.ZERO) == 0) {
serverTextChannel.sendMessage("You can't bet 0 beanCoin!");
} else {
if (points.removePoints(author.getIdAsString(), api.getYourself().getIdAsString(), server.getIdAsString(), winningPoints)) {
if (points.removePoints(author.getIdAsString(), null, server.getIdAsString(), winningPoints)) {
Random rand = new Random();
int winningChance = rand.nextInt(100) + 1;

Expand Down Expand Up @@ -67,6 +67,7 @@ public void onCommand(String[] args, DiscordApi api, ServerTextChannel serverTex
}
} else {
serverTextChannel.sendMessage("Sorry, you lost " + Points.pointsToString(winningPoints) + ".");
points.addPoints(api.getYourself().getIdAsString(), server.getIdAsString(), winningPoints);
Sentry.getContext().recordBreadcrumb(
new BreadcrumbBuilder()
.setMessage("User lost")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import de.btobastian.sdcf4j.Command;
import de.btobastian.sdcf4j.CommandExecutor;
import io.sentry.Sentry;
import org.apache.commons.lang3.StringUtils;
import org.javacord.api.DiscordApi;
import org.javacord.api.entity.channel.ServerTextChannel;
import org.javacord.api.entity.message.MessageBuilder;
Expand Down Expand Up @@ -36,77 +37,93 @@ public BeanLotteryCommand(Points points, Lottery lottery) {
public void onCommand(String[] args, DiscordApi api, ServerTextChannel serverTextChannel, User author, Server server) {
SentryLog.addContext(args, author, server);

if (args.length == 1) {
if (args[0].equalsIgnoreCase("start")) {
if (!author.isBotOwner() && !server.isOwner(author)) {
try {
serverTextChannel.sendMessage("Only " + api.getOwner().get().getDiscriminatedName() + " or " + server.getOwner().getDisplayName(server) + " can use this command.");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
return;
} else {
serverTextChannel.sendMessage("Weekly drawings now active. When the bot has more than " + Points.pointsToString(Lottery.MIN_WEEKLY_VALUE) + " it will do an automatic drawing every 7 days.");
lottery.scheduleWeeklyDrawing(points, server, api, serverTextChannel);
return;
if (args.length == 1) {
if (args[0].equalsIgnoreCase("start")) {
if (!author.isBotOwner() && !server.isOwner(author)) {
try {
serverTextChannel.sendMessage("Only " + api.getOwner().get().getDiscriminatedName() + " or " + server.getOwner().getDisplayName(server) + " can use this command.");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
} //else if (args[0].equalsIgnoreCase("draw")) {
return;
} else {
serverTextChannel.sendMessage("Automatic drawings now active. Drawing will happen at this time every 3 days.");
lottery.scheduleWeeklyDrawing(points, server, api, serverTextChannel);
return;
}
} //else if (args[0].equalsIgnoreCase("draw")) {
// if (points.removePoints(author.getIdAsString(), api.getYourself().getIdAsString(), server.getIdAsString(), Points.LOTTERY_DRAWING_COST)) {
// lottery.drawNumbers(points, server, api, serverTextChannel);
// } else
// serverTextChannel.sendMessage("You do not have enough beanCoin for this command");
// return;
// }
if (Integer.parseInt(args[0]) > 200) {
serverTextChannel.sendMessage("You can only buy 200 tickets at a time.");
return;
}
if (Integer.parseInt(args[0]) > 200) {
serverTextChannel.sendMessage("You can only buy 200 tickets at a time.");
return;
}

if (Integer.parseInt(args[0]) < 1) {
serverTextChannel.sendMessage("You cannot buy less than 1 ticket.");
return;
if (Integer.parseInt(args[0]) < 1) {
serverTextChannel.sendMessage("You cannot buy less than 1 ticket.");
return;
}

if (!lottery.canBuyTickets(author.getIdAsString(), server.getIdAsString(), Integer.parseInt(args[0]))) {
serverTextChannel.sendMessage("You can only buy " + Lottery.MAX_TICKETS + " tickets at a time for a bean lottery drawing. You have bought " + lottery.getTicketCount(author.getIdAsString(), server.getIdAsString()) + " tickets.");
return;
}

if (points.removePoints(author.getIdAsString(), api.getYourself().getIdAsString(), server.getIdAsString(), Points.LOTTERY_TICKET_COST.multiply(new BigDecimal(Integer.parseInt(args[0]))))) {

ArrayList<ArrayList<Integer>> numbers = lottery.addEntry(author.getIdAsString(), server.getIdAsString(), Integer.parseInt(args[0]));

serverTextChannel.sendMessage(args[0] + " tickets bought.\n" +
"The numbers generated have been sent to you in a private message.");
author.sendMessage(args[0] + " tickets bought.\n" +
"Your numbers are:");
MessageBuilder message = new MessageBuilder();

for (int i = 0; i < numbers.size(); i++) {
for (int j = 0; j < Lottery.AMOUNT_DRAWN; j++)
message.append(numbers.get(i).get(j) + " ");
message.append("\n");
}
message.send(author);
} else
serverTextChannel.sendMessage("You don't have enough beanCoin to buy that many tickets.");
} else if (args.length >= Lottery.AMOUNT_DRAWN) {
if (!StringUtils.isNumeric(args[0])) {
serverTextChannel.sendMessage("Invalid amount.");
return;
}

if (points.removePoints(author.getIdAsString(), api.getYourself().getIdAsString(), server.getIdAsString(), Points.LOTTERY_TICKET_COST.multiply(new BigDecimal(Integer.parseInt(args[0]))))) {
ArrayList<ArrayList<Integer>> numbers = lottery.addEntry(author.getIdAsString(), server.getIdAsString(), Integer.parseInt(args[0]));
if (!lottery.canBuyTickets(author.getIdAsString(), server.getIdAsString(), 1)) {
serverTextChannel.sendMessage("You can only buy " + Lottery.MAX_TICKETS + " tickets at a time for a bean lottery drawing. You have bought " + lottery.getTicketCount(author.getIdAsString(), server.getIdAsString()) + " tickets.");
return;
}

serverTextChannel.sendMessage(args[0] + " tickets bought.\n" +
"The numbers generated have been sent to you in a private message.");
author.sendMessage(args[0] + " tickets bought.\n" +
"Your numbers are:");
MessageBuilder message = new MessageBuilder();
int[] numbers = new int[Lottery.AMOUNT_DRAWN];

for (int i = 0; i < numbers.size(); i++) {
for (int j = 0; j < Lottery.AMOUNT_DRAWN; j++)
message.append(numbers.get(i).get(j) + " ");
message.append("\n");
}
message.send(author);
} else
serverTextChannel.sendMessage("You don't have enough beanCoin to buy that many tickets.");
} else if (args.length >= Lottery.AMOUNT_DRAWN) {
int[] numbers = new int[Lottery.AMOUNT_DRAWN];

for (int i = 0; i < Lottery.AMOUNT_DRAWN; i++) {
if (Integer.parseInt(args[i]) >= Lottery.MIN_NUMBER && Integer.parseInt(args[i]) <= Lottery.MAX_NUMBER)
numbers[i] = Integer.parseInt(args[i]);
else {
serverTextChannel.sendMessage(args[i] + " is an invalid number. Numbers must be greater than or equal to " + Lottery.MIN_NUMBER + " and less than or equal to " + Lottery.MAX_NUMBER);
return;
}
for (int i = 0; i < Lottery.AMOUNT_DRAWN; i++) {
if (Integer.parseInt(args[i]) >= Lottery.MIN_NUMBER && Integer.parseInt(args[i]) <= Lottery.MAX_NUMBER)
numbers[i] = Integer.parseInt(args[i]);
else {
serverTextChannel.sendMessage(args[i] + " is an invalid number. Numbers must be greater than or equal to " + Lottery.MIN_NUMBER + " and less than or equal to " + Lottery.MAX_NUMBER);
return;
}
if (points.removePoints(author.getIdAsString(), api.getYourself().getIdAsString(), server.getIdAsString(), Points.LOTTERY_TICKET_COST)) {
lottery.addEntry(author.getIdAsString(), server.getIdAsString(), numbers);

serverTextChannel.sendMessage("1 ticket bought.\n" +
"Your numbers have been sent to you in a private message.");
author.sendMessage("1 ticket bought.\n" +
"Your numbers are:\n");
author.sendMessage(args[0] + " " + args[1] + " " + args[2]);
} else
serverTextChannel.sendMessage("You do not have enough beanCoin to buy a ticket.");
}
if (points.removePoints(author.getIdAsString(), api.getYourself().getIdAsString(), server.getIdAsString(), Points.LOTTERY_TICKET_COST)) {
lottery.addEntry(author.getIdAsString(), server.getIdAsString(), numbers);

serverTextChannel.sendMessage("1 ticket bought.\n" +
"Your numbers have been sent to you in a private message.");
author.sendMessage("1 ticket bought.\n" +
"Your numbers are:\n");
author.sendMessage(args[0] + " " + args[1] + " " + args[2]);
} else
serverTextChannel.sendMessage("You must have 1 number with how many tickets you want to buy, " + Lottery.AMOUNT_DRAWN + " numbers >= " + Lottery.MIN_NUMBER + " and <= " + Lottery.MAX_NUMBER + ", or the word `draw` to have your own drawing.");
serverTextChannel.sendMessage("You do not have enough beanCoin to buy a ticket.");
} else
serverTextChannel.sendMessage("You must have 1 number with how many tickets you want to buy, " + Lottery.AMOUNT_DRAWN + " numbers >= " + Lottery.MIN_NUMBER + " and <= " + Lottery.MAX_NUMBER + ", or the word `draw` to have your own drawing.");

Sentry.clearContext();
}
Expand Down
Loading

0 comments on commit 631f242

Please sign in to comment.