Search in sources :

Example 1 with MiniGame

use of tel.discord.rtab.games.MiniGame 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 MiniGame

use of tel.discord.rtab.games.MiniGame 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 MiniGame

use of tel.discord.rtab.games.MiniGame in project RtaB6 by Telnaior.

the class GameController method prepareNextMiniGame.

private void prepareNextMiniGame(ListIterator<Game> gamesToPlay) {
    if (gamesToPlay.hasNext()) {
        // Get the minigame
        Game nextGame = gamesToPlay.next();
        currentGame = nextGame.getGame();
        // Count the number of copies
        int multiplier = 1;
        while (gamesToPlay.hasNext()) {
            // Move the iterator back one, to the first instance of the game
            gamesToPlay.previous();
            // If it matches (ie multiple copies), remove one and add it to the multiplier
            if (gamesToPlay.next() == gamesToPlay.next()) {
                multiplier++;
                gamesToPlay.remove();
            } else // Otherwise we'd better put it back where it belongs
            {
                gamesToPlay.previous();
                break;
            }
        }
        // Pass to the game
        boolean sendMessages = !(players.get(currentTurn).isBot) || verboseBotGames;
        // Set up the thread we'll send to the game
        Thread postGame = new Thread() {

            public void run() {
                // Recurse to get to the next minigame
                currentGame = null;
                if (players.get(currentTurn).games.size() > 0)
                    prepareNextMiniGame(players.get(currentTurn).games.listIterator(gamesToPlay.nextIndex()));
                else
                    runNextEndGamePlayer();
            }
        };
        postGame.setName(String.format("%s - %s - %s", channel.getName(), players.get(currentTurn).getName(), currentGame.getName()));
        currentGame.initialiseGame(channel, sendMessages, baseNumerator, baseDenominator, multiplier, players, currentTurn, postGame, players.get(currentTurn).enhancedGames.contains(nextGame));
    } else {
        // Check for winning the game
        if (players.get(currentTurn).money >= 1000000000 && players.get(currentTurn).status == PlayerStatus.DONE) {
            winners.add(players.get(currentTurn));
        }
        runNextEndGamePlayer();
    }
}
Also used : Game(tel.discord.rtab.board.Game) MiniGame(tel.discord.rtab.games.MiniGame)

Aggregations

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