Search in sources :

Example 1 with Game

use of tel.discord.rtab.board.Game in project RtaB6 by Telnaior.

the class GameController method displayBoardAndStatus.

public void displayBoardAndStatus(boolean printBoard, boolean totals, boolean copyToResultChannel) {
    if (gameStatus == GameStatus.SIGNUPS_OPEN) {
        // No board to display if the game isn't running!
        return;
    }
    StringBuilder board = new StringBuilder().append("```\n");
    // Board doesn't need to be displayed if game is over
    if (printBoard) {
        // Do we need a complex header, or should we use the simple one?
        int boardWidth = Math.max(5, players.size() + 1);
        if (boardWidth < 6)
            board.append("     RtaB     \n");
        else {
            for (int i = 7; i <= boardWidth; i++) {
                // One space for odd numbers, two spaces for even numbers
                board.append(i % 2 == 0 ? "  " : " ");
            }
            // Then print the first part
            board.append("Race to ");
            // Extra space if it's odd
            if (boardWidth % 2 == 1)
                board.append(" ");
            // Then the rest of the header
            board.append("a Billion\n");
        }
        for (int i = 0; i < boardSize; i++) {
            board.append(pickedSpaces[i] ? "  " : String.format("%02d", (i + 1)));
            board.append((i % boardWidth) == (boardWidth - 1) ? "\n" : " ");
        }
        board.append("\n");
    }
    // Next the status line
    // Start by getting the lengths so we can pad the status bars appropriately
    // Add one extra to name length because we want one extra space between name and cash
    int nameLength = players.get(0).getName().length();
    for (int i = 1; i < players.size(); i++) nameLength = Math.max(nameLength, players.get(i).getName().length());
    nameLength++;
    // And ignore the negative sign if there is one
    int moneyLength;
    if (totals) {
        moneyLength = String.valueOf(Math.abs(players.get(0).money)).length();
        for (int i = 1; i < players.size(); i++) moneyLength = Math.max(moneyLength, String.valueOf(Math.abs(players.get(i).money)).length());
    } else {
        moneyLength = String.valueOf(Math.abs(players.get(0).getRoundDelta())).length();
        for (int i = 1; i < players.size(); i++) moneyLength = Math.max(moneyLength, String.valueOf(Math.abs(players.get(i).getRoundDelta())).length());
    }
    // Make a little extra room for the commas
    moneyLength += (moneyLength - 1) / 3;
    // Then start printing - including pointer if currently their turn
    for (int i = 0; i < players.size(); i++) {
        board.append(currentTurn == i ? "> " : "  ");
        board.append(String.format("%-" + nameLength + "s", players.get(i).getName()));
        // Now figure out if we need a negative sign, a space, or neither
        int playerMoney = players.get(i).getRoundDelta();
        // What sign to print?
        board.append(playerMoney < 0 ? "-" : "+");
        // Then print the money itself
        board.append(String.format("$%," + moneyLength + "d", Math.abs(playerMoney)));
        // Now the booster display
        switch(players.get(i).status) {
            case ALIVE:
            case DONE:
                // If they're alive, display their booster
                board.append(String.format(" [%3d%%", players.get(i).booster));
                // If it's endgame, show their winstreak afterward
                if (players.get(i).status == PlayerStatus.DONE || (gameStatus == GameStatus.END_GAME && currentTurn == i))
                    board.append(String.format("x%1$d.%2$d", players.get(i).winstreak / 10, players.get(i).winstreak % 10));
                else // Otherwise, display whether or not they have a peek
                if (players.get(i).peeks > 0)
                    board.append("P");
                else
                    board.append(" ");
                // Then close off the bracket
                board.append("]");
                break;
            case OUT:
            case FOLDED:
                board.append("  [OUT] ");
                break;
            case WINNER:
                board.append("  [WIN] ");
        }
        // If they have any games, print them too
        if (players.get(i).games.size() > 0) {
            board.append(" {");
            for (Game minigame : players.get(i).games) {
                board.append(" " + minigame.getShortName());
            }
            board.append(" }");
        }
        board.append("\n");
        // If we want the totals as well, do them on a second line
        if (totals) {
            // Get to the right spot in the line
            for (int j = 0; j < (nameLength - 4); j++) board.append(" ");
            board.append("Total:");
            // Print sign
            board.append(players.get(i).money < 0 ? "-" : " ");
            // Then print the money itself
            board.append("$");
            board.append(String.format("%," + moneyLength + "d\n\n", Math.abs(players.get(i).money)));
        }
    }
    // Close it off and print it out
    board.append("```");
    channel.sendMessage(board.toString()).queue();
    if (copyToResultChannel && resultChannel != null)
        resultChannel.sendMessage(board.toString()).queue();
}
Also used : Game(tel.discord.rtab.board.Game) MiniGame(tel.discord.rtab.games.MiniGame)

Example 2 with Game

use of tel.discord.rtab.board.Game in project RtaB6 by Telnaior.

the class GameController method saveData.

private void saveData() {
    try {
        List<String> list = Files.readAllLines(Paths.get("scores", "scores" + channel.getId() + ".csv"));
        // Go through each player in the game to update their stats
        for (int i = 0; i < players.size(); i++) {
            /*
				 * Special case - if you lose the round with $1B you get bumped to $999,999,999
				 * so that an elimination without penalty (eg bribe) doesn't get you declared champion
				 * This is since you haven't won yet, after all (and it's *extremely* rare to win a round without turning a profit)
				 * Note that in the instance of a final showdown, both players are temporarily labelled champion
				 * But after the tie is resolved, one will be bumped back to $900M
				 */
            if (players.get(i).money == 1_000_000_000 && players.get(i).status != PlayerStatus.DONE)
                players.get(i).money--;
            // Send messages based on special status
            if (// Out of newbie protection
            players.get(i).newbieProtection == 1)
                channel.sendMessage(players.get(i).getSafeMention() + ", your newbie protection has expired. " + "From now on, your base bomb penalty will be $250,000.").queue();
            if (players.get(i).totalLivesSpent % 5 == 0 && players.get(i).getEnhanceCap() > players.get(i).enhancedGames.size()) {
                // Just earned an enhancement (or spent 5 lives with an open slot - we don't want to remind them every game)
                if (players.get(i).isBot) {
                    /* Bots need to pick a minigame to enhance on their own, so we do that now
						 * But first, check to make sure there is a minigame to put in that slot
						 * (In ultra-low base-multiplier seasons, this might actually be an issue)
						 * (It'd take roughly 3000 lives spent though)
						 */
                    int enhanceableGames = 0;
                    for (Game next : Game.values()) if (next.getWeight(players.size()) > 0)
                        enhanceableGames++;
                    if (players.get(i).enhancedGames.size() < enhanceableGames) {
                        Game chosenGame;
                        do {
                            chosenGame = Board.generateSpaces(1, players.size(), Game.values()).get(0);
                        } while (// Reroll until we find one they haven't already done
                        players.get(i).enhancedGames.contains(chosenGame));
                        players.get(i).enhancedGames.add(chosenGame);
                        channel.sendMessage(players.get(i).getName() + " earned an enhancement slot and chose to enhance " + chosenGame.getName() + "!").queue();
                    }
                } else
                    channel.sendMessage(players.get(i).getSafeMention() + ", you have earned an enhancement slot! " + "Use the !enhance command to pick a minigame to enhance.").queue();
            }
            // Find if they already exist in the savefile, and where
            String[] record;
            int location = -1;
            for (int j = 0; j < list.size(); j++) {
                record = list.get(j).split("#");
                if (record[0].compareToIgnoreCase(players.get(i).uID) == 0) {
                    location = j;
                    break;
                }
            }
            // Then build their record and put it in the right place
            StringBuilder toPrint = new StringBuilder();
            toPrint.append(players.get(i).uID);
            toPrint.append("#" + players.get(i).getName());
            toPrint.append("#" + players.get(i).money);
            toPrint.append("#" + players.get(i).booster);
            toPrint.append("#" + players.get(i).winstreak);
            toPrint.append("#" + Math.max(players.get(i).newbieProtection - 1, 0));
            toPrint.append("#" + players.get(i).lives);
            toPrint.append("#" + players.get(i).lifeRefillTime);
            toPrint.append("#" + players.get(i).hiddenCommand);
            toPrint.append("#" + players.get(i).boostCharge);
            toPrint.append("#" + players.get(i).annuities);
            toPrint.append("#" + players.get(i).totalLivesSpent);
            toPrint.append("#" + players.get(i).enhancedGames);
            // If they already exist in the savefile then replace their record, otherwise add them
            if (location == -1)
                list.add(toPrint.toString());
            else
                list.set(location, toPrint.toString());
            // Update their player level if relevant
            if (playersLevelUp) {
                PlayerLevel playerLevelData = new PlayerLevel(channel.getGuild().getId(), players.get(i).uID, players.get(i).getName());
                boolean levelUp = playerLevelData.addXP(players.get(i).money - players.get(i).originalMoney);
                if (levelUp)
                    channel.sendMessage(players.get(i).getSafeMention() + " has achieved Level " + playerLevelData.getTotalLevel() + "!").queue();
                playerLevelData.saveLevel();
            }
            // Update a player's role if it's the role channel, they're human, and have earned a new one
            if (players.get(i).money / 100_000_000 != players.get(i).currentCashClub && !players.get(i).isBot && rankChannel) {
                // Get the mod controls
                Guild guild = channel.getGuild();
                List<Role> rolesToAdd = new LinkedList<>();
                List<Role> rolesToRemove = new LinkedList<>();
                // Remove their old score role if they had one
                if (players.get(i).originalMoney / 100_000_000 > 0 && players.get(i).originalMoney / 100_000_000 < 10)
                    rolesToRemove.addAll(guild.getRolesByName(String.format("$%d00M", players.get(i).originalMoney / 100_000_000), false));
                else // Special case for removing Champion role in case of final showdown
                if (players.get(i).originalMoney / 100_000_000 == 10)
                    rolesToRemove.addAll(guild.getRolesByName("Champion", false));
                // Add their new score role if they deserve one
                if (players.get(i).money / 100_000_000 > 0 && players.get(i).money / 100_000_000 < 10)
                    rolesToAdd.addAll(guild.getRolesByName(String.format("$%d00M", players.get(i).money / 100_000_000), false));
                else // Or do fancy stuff for the Champion
                if (players.get(i).money / 100_000_000 == 10)
                    rolesToAdd.addAll(guild.getRolesByName("Champion", false));
                // Then add/remove appropriately
                guild.modifyMemberRoles(players.get(i).member, rolesToAdd, rolesToRemove).queue();
            }
        }
        // Then sort and rewrite it
        list.sort(new DescendingScoreSorter());
        Path file = Paths.get("scores", "scores" + channel.getId() + ".csv");
        Path oldFile = Files.move(file, file.resolveSibling("scores" + channel.getId() + "old.csv"));
        Files.write(file, list);
        Files.delete(oldFile);
    } catch (IOException e) {
        System.err.println("Could not save data in " + channel.getName());
        e.printStackTrace();
    }
}
Also used : Path(java.nio.file.Path) IOException(java.io.IOException) Guild(net.dv8tion.jda.api.entities.Guild) LinkedList(java.util.LinkedList) Role(net.dv8tion.jda.api.entities.Role) Game(tel.discord.rtab.board.Game) MiniGame(tel.discord.rtab.games.MiniGame)

Example 3 with Game

use of tel.discord.rtab.board.Game in project RtaB6 by Telnaior.

the class EnhanceCommand method execute.

@Override
protected void execute(CommandEvent event) {
    // Check if they just want the list
    if (event.getArgs().equalsIgnoreCase("list")) {
        sendEnhanceList(event);
        return;
    }
    // Next check if they've picked a game to enhance
    String gameName = event.getArgs();
    // Run through the list of games to find the one they asked for
    for (Game game : Game.values()) {
        if (gameName.equalsIgnoreCase(game.getShortName()) || gameName.equalsIgnoreCase(game.getName())) {
            enhanceGame(event, game);
            return;
        }
    }
    // If they don't seem to be enhancing a minigame, just send them their status
    // Start by checking to see if they're in-game, and read from their player-file instead
    Player player = null;
    // Find the channel
    GameController controller = null;
    for (GameController next : RaceToABillionBot.game) if (next.channel.equals(event.getChannel())) {
        controller = next;
        break;
    }
    if (controller == null) {
        event.reply("This command must be used in a game channel.");
        return;
    }
    for (Player next : controller.players) if (next.uID.equals(event.getAuthor().getId())) {
        player = next;
        break;
    }
    // If they aren't in-game, get their data by generating their player object
    if (player == null) {
        player = new Player(event.getMember(), controller, null);
    }
    // Now let's start building up the reply message
    StringBuilder output = new StringBuilder();
    // List their enhance slot status
    output.append("```\n" + player.getName() + "'s Enhanced Minigames:\n");
    boolean emptySlots = false;
    for (int i = 0; i < player.getEnhanceCap(); i++) {
        if (i < player.enhancedGames.size()) {
            output.append(" (*) ");
            output.append(player.enhancedGames.get(i).getName());
        } else {
            output.append(" ( ) Empty Slot");
            emptySlots = true;
        }
        output.append("\n");
    }
    int livesToNewSlot = (25 * (player.getEnhanceCap() + 1) * (player.getEnhanceCap() + 2) / 2) - player.totalLivesSpent;
    if (player.newbieProtection > 0)
        output.append("     (Finish your newbie protection, then use " + livesToNewSlot + " lives to open a new slot)\n\n");
    else
        output.append("     (Use " + livesToNewSlot + " more lives to open a new slot)\n\n");
    output.append("Type '!enhance list' to see the list of available enhancements.\n");
    if (emptySlots)
        output.append("Type '!enhance' followed by a minigame's name to permanently enhance that minigame.\n");
    output.append("```");
    event.reply(output.toString());
}
Also used : Player(tel.discord.rtab.Player) Game(tel.discord.rtab.board.Game) GameController(tel.discord.rtab.GameController)

Example 4 with Game

use of tel.discord.rtab.board.Game in project RtaB6 by Telnaior.

the class EnhanceCommand method enhanceGame.

void enhanceGame(CommandEvent event, Game game) {
    // First of all, is the game actually in this season?
    if (game.getWeight(4) <= 0) {
        event.reply("That minigame is not available this season.");
        return;
    }
    // Find the channel
    GameController controller = null;
    for (GameController next : RaceToABillionBot.game) if (next.channel.equals(event.getChannel())) {
        controller = next;
        break;
    }
    if (controller == null) {
        event.reply("This command must be used in a game channel.");
        return;
    }
    // Check that they're in game currently, or that there's no game running
    if (controller.players.size() <= 0) {
        // If there's no game running, find them in the savefile
        try {
            List<String> list = Files.readAllLines(Paths.get("scores", "scores" + event.getChannel().getId() + ".csv"));
            int index = findUserInList(list, event.getAuthor().getId(), false);
            if (index < 0 || index >= list.size()) {
                event.reply("You currently have no open enhance slots.");
                return;
            }
            String[] record = list.get(index).split("#");
            /*
				 * record[11] = total lives spent
				 * record[12] = list of enhanced minigames
				 * (this is copied directly from the player initialisation file)
				 */
            int totalLivesSpent = Integer.parseInt(record[11]);
            ArrayList<Game> enhancedGames = new ArrayList<Game>();
            // Remove the brackets
            String savedEnhancedGames = record[12].substring(1, record[12].length() - 1);
            String[] enhancedList = savedEnhancedGames.split(",");
            if (enhancedList[0].length() > 0)
                for (int j = 0; j < enhancedList.length; j++) enhancedGames.add(Game.valueOf(enhancedList[j].trim()));
            // Do the obvious checks
            if (RtaBMath.getEnhanceCap(totalLivesSpent) <= enhancedGames.size()) {
                event.reply("You currently have no open enhance slots.");
                return;
            }
            for (Game nextGame : enhancedGames) {
                if (game == nextGame) {
                    event.reply("You have already enhanced that minigame.");
                    return;
                }
            }
            // Enhance it!
            enhancedGames.add(game);
            event.reply("Minigame enhanced!");
            // Now replace the record in the list
            StringBuilder updatedLine = new StringBuilder();
            for (int i = 0; i < 11; i++) {
                updatedLine.append(record[i]);
                updatedLine.append("#");
            }
            updatedLine.append(totalLivesSpent);
            updatedLine.append("#");
            updatedLine.append(enhancedGames.toString());
            list.set(index, updatedLine.toString());
            // And save it
            Path file = Paths.get("scores", "scores" + event.getChannel().getId() + ".csv");
            Path oldFile = Files.move(file, file.resolveSibling("scores" + event.getChannel().getId() + "old.csv"));
            Files.write(file, list);
            Files.delete(oldFile);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return;
    }
    boolean playerFound = false;
    for (Player next : controller.players) if (next.uID.equals(event.getAuthor().getId())) {
        playerFound = true;
        if (next.getEnhanceCap() <= next.enhancedGames.size()) {
            event.reply("You currently have no open enhance slots.");
            return;
        }
        for (Game nextGame : next.enhancedGames) {
            if (game == nextGame) {
                event.reply("You have already enhanced that minigame.");
                return;
            }
        }
        // Yay they actually met all the conditions was that so hard
        next.enhancedGames.add(game);
        event.reply("Minigame enhanced!");
    }
    if (!playerFound) {
        event.reply("There is a game currently in progress; please wait until it is finished to enhance.");
        return;
    }
}
Also used : Path(java.nio.file.Path) Player(tel.discord.rtab.Player) ArrayList(java.util.ArrayList) IOException(java.io.IOException) Game(tel.discord.rtab.board.Game) GameController(tel.discord.rtab.GameController)

Example 5 with Game

use of tel.discord.rtab.board.Game in project RtaB6 by Telnaior.

the class MinigamesForAll method execute.

@Override
public void execute(GameController game, int player) {
    // Small chance in large games of the space mutating, capping at 10% in 16p
    if (Math.random() * 100 < game.playersAlive - 6) {
        game.channel.sendMessage("It's **Minigame For... One?!**").queue();
        Game chosenGame = game.generateEventMinigame(player);
        for (int i = 0; i < game.playersAlive; i++) {
            game.players.get(player).games.add(chosenGame);
            game.channel.sendMessage(game.players.get(player).getSafeMention() + " receives a copy of **" + chosenGame.getName() + "**!").queue();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        game.players.get(player).games.sort(null);
        game.players.get(player).minigameLock = true;
        game.channel.sendMessage("Minigame Lock applied to " + game.players.get(player).getSafeMention() + ".").queue();
    } else {
        game.channel.sendMessage("It's **Minigames For All**! All players remaining receive a minigame!").queue();
        for (int i = 0; i < game.players.size(); i++) {
            Player nextPlayer = game.players.get(i);
            if (nextPlayer.status == PlayerStatus.ALIVE) {
                Game chosenGame = game.generateEventMinigame(i);
                game.players.get(i).games.add(chosenGame);
                game.players.get(i).games.sort(null);
                game.channel.sendMessage(nextPlayer.getSafeMention() + " receives a copy of **" + chosenGame.getName() + "**!").queue();
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
Also used : Player(tel.discord.rtab.Player) Game(tel.discord.rtab.board.Game)

Aggregations

Game (tel.discord.rtab.board.Game)9 Player (tel.discord.rtab.Player)3 MiniGame (tel.discord.rtab.games.MiniGame)3 IOException (java.io.IOException)2 Path (java.nio.file.Path)2 ArrayList (java.util.ArrayList)2 GameController (tel.discord.rtab.GameController)2 LinkedList (java.util.LinkedList)1 Guild (net.dv8tion.jda.api.entities.Guild)1 Role (net.dv8tion.jda.api.entities.Role)1