use of tel.discord.rtab.board.SpaceType in project RtaB6 by Telnaior.
the class GameController method useTruesight.
public String useTruesight(int player, int space) {
Player eyeballer = players.get(player);
if (player == currentTurn) {
peekStreak++;
if (peekStreak == 3)
Achievement.EXTRA_PEEKS.check(eyeballer);
}
channel.sendMessage(eyeballer.getName() + " used an Eye of Truth to look at space " + (space + 1) + "!").queue();
eyeballer.hiddenCommand = HiddenCommand.NONE;
String spaceIdentity = gameboard.truesightSpace(space, baseNumerator, baseDenominator);
SpaceType peekedSpace = gameboard.getType(space);
// Add the space to the internal list, the same as with a regular peek
if (peekedSpace.isBomb())
eyeballer.knownBombs.add(space);
else
// Otherwise add it to their known safe spaces
eyeballer.safePeeks.add(space);
if (!eyeballer.isBot)
eyeballer.user.openPrivateChannel().queue((channel) -> channel.sendMessage(String.format("Space %d: **%s**.", space + 1, spaceIdentity)).queue());
return spaceIdentity;
}
use of tel.discord.rtab.board.SpaceType in project RtaB6 by Telnaior.
the class GameController method runTurn.
private void runTurn(int player) {
// There is NO reason why we should be running a turn for anyone other than the current player
if (player != currentTurn)
return;
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// If someone from the Gallery has given our hapless player a blammo, they get that instead of their normal turn
if (futureBlammo) {
futureBlammo = false;
resolvingTurn = true;
if (repeatTurn > 0)
repeatTurn--;
channel.sendMessage(players.get(player).getSafeMention() + ", someone from the gallery has given you a **BLAMMO!**").queue();
startBlammo(player, false);
return;
}
// Count down if necessary
if (finalCountdown) {
// End the game if we're out of turns
if (fcTurnsLeft == 0) {
gameOver();
return;
} else // Otherwise display the appropriate message
if (fcTurnsLeft == 1)
channel.sendMessage("The round will end **after this pick!**").queue();
else
channel.sendMessage(String.format("The round will end in **%d picks**.", fcTurnsLeft)).queue();
// And then subtract one
fcTurnsLeft--;
}
// Figure out who to ping and what to tell them
if (repeatTurn > 0 && !firstPick) {
if (!(players.get(player).isBot))
channel.sendMessage(players.get(player).getSafeMention() + ", pick again.").queue();
} else {
firstPick = false;
if (!players.get(player).isBot)
channel.sendMessage(players.get(player).getSafeMention() + ", your turn. Choose a space on the board.").queue();
}
if (repeatTurn > 0)
repeatTurn--;
displayBoardAndStatus(true, false, false);
// Ready up the space picker depending on if it's a bot up next
if (players.get(player).isBot) {
// Sleep for a couple of seconds so they don't rush
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// Get safe spaces, starting with all unpicked spaces
ArrayList<Integer> openSpaces = new ArrayList<>(boardSize);
for (int i = 0; i < boardSize; i++) if (!pickedSpaces[i])
openSpaces.add(i);
// Remove all known bombs
ArrayList<Integer> safeSpaces = new ArrayList<>(boardSize);
safeSpaces.addAll(openSpaces);
for (Integer bomb : players.get(player).knownBombs) safeSpaces.remove(bomb);
// Test for hidden command stuff
switch(players.get(player).hiddenCommand) {
// Fold if they have no peeks, jokers, there's been no starman, and a random chance is hit
case FOLD:
if (!starman && players.get(player).peeks < 1 && players.get(player).jokers == 0 && Math.random() * spacesLeft < 1) {
useFold(player);
return;
}
break;
// Bonus bag under same condition as the fold, but more frequently because of its positive effect
case BONUS:
if (!starman && players.get(player).peeks < 1 && players.get(player).jokers == 0 && Math.random() * spacesLeft < 3) {
// Let's just pick one randomly
SpaceType desire = SpaceType.BOOSTER;
if (Math.random() * 2 < 1)
desire = SpaceType.GAME;
if (Math.random() * 3 < 1)
desire = SpaceType.CASH;
if (Math.random() * 4 < 1)
desire = SpaceType.EVENT;
useBonusBag(player, desire);
return;
}
break;
// But do increase the chance for it compared to folding
case BLAMMO:
if (!starman && players.get(player).peeks < 1 && repeatTurn == 0 && players.get(player).jokers == 0 && Math.random() * spacesLeft < players.size())
useBlammoSummoner(player);
break;
// Teeeeeechnically it isn't playing to win with this, but it is making the game more exciting for the real players.
case WAGER:
if (players.size() * 4 < spacesLeft)
useWager(player);
break;
// Truesight under the same condition as a peek
case TRUESIGHT:
if (safeSpaces.size() > 1 && Math.random() < 0.5) {
int truesightIndex = (int) (Math.random() * safeSpaces.size());
int truesightSpace = safeSpaces.get(truesightIndex);
if (!players.get(player).safePeeks.contains(truesightSpace)) {
// We know there's another so this is fine
safeSpaces.remove(truesightIndex);
String truesightIdentity = useTruesight(player, truesightSpace);
boolean badPeek = false;
if (truesightIdentity.startsWith("-") || truesightIdentity.contains("BOMB"))
badPeek = true;
else
switch(truesightIdentity) {
case "BLAMMO":
case "Split & Share":
case "Bowser Event":
case "Reverse":
case "Minefield":
badPeek = true;
}
if (!badPeek) {
resolveTurn(player, truesightSpace);
return;
}
}
}
break;
// With minesweeper, look for an opportunity every turn
case MINESWEEP:
if (safeSpaces.size() > 1) {
// Look for a space with only one adjacent to it
ArrayList<Integer> minesweepOpportunities = new ArrayList<Integer>();
for (int i = 0; i < boardSize; i++) if (!pickedSpaces[i]) {
int adjacentSpaces = 0;
for (int j : RtaBMath.getAdjacentSpaces(i, players.size())) if (!pickedSpaces[j])
adjacentSpaces++;
if (adjacentSpaces == 1)
minesweepOpportunities.add(i);
}
// If we found one, choose one at random to sweep
if (minesweepOpportunities.size() > 0)
useMinesweeper(player, minesweepOpportunities.get((int) (Math.random() * minesweepOpportunities.size())));
}
// Repel/Defuse/Failsafe are more situational and aren't used at this time
default:
break;
}
// With chance depending on current board risk, look for a previous peek to use
if (Math.random() * (spacesLeft - 1) < playersAlive) {
// Check for known peeked spaces that are still available
ArrayList<Integer> peekedSpaces = new ArrayList<>(boardSize);
for (Integer peek : players.get(player).safePeeks) {
if (openSpaces.contains(peek))
peekedSpaces.add(peek);
}
// If there's any, pick one and end our logic
if (peekedSpaces.size() > 0) {
resolveTurn(player, peekedSpaces.get((int) (Math.random() * peekedSpaces.size())));
return;
}
}
// If there's any spaces that aren't known bombs, pick one and resolve it
if (safeSpaces.size() > 0) {
/*
* Use a peek under the following conditions:
* - The bot has one to use
* - It hasn't already peeked the space selected
* - 50% chance (so it won't always fire immediately)
* Note that they never bluff peek their own bomb (it's just easier that way)
*/
if (players.get(player).peeks > 0 && safeSpaces.size() > 1 && Math.random() < 0.5) {
int peekSpace = safeSpaces.get((int) (Math.random() * safeSpaces.size()));
// Don't use the peek if we've already seen this space
if (!players.get(player).safePeeks.contains(peekSpace)) {
// Let the players know what's going on
channel.sendMessage("(" + players.get(player).getName() + " peeks space " + (peekSpace + 1) + ")").queue();
// Then use the peek, and decide what to do from there
switch(usePeek(player, peekSpace)) {
// If it's a minigame or booster, take it immediately - it's guaranteed safe
case BOOSTER:
case GAME:
resolveTurn(player, peekSpace);
break;
// Blammos and grab bags peek as cash and event respectively, so the bot handles them this way too
case CASH:
case EVENT:
case GRAB_BAG:
case BLAMMO:
if (Math.random() < 0.5 || players.size() == 2)
resolveTurn(player, peekSpace);
else
resolveTurn(player, safeSpaces.get((int) (Math.random() * safeSpaces.size())));
break;
// And obviously, don't pick it if it's a bomb!
case BOMB:
case GB_BOMB:
safeSpaces.remove(new Integer(peekSpace));
// Make sure there's still a safe space left to pick, otherwise BAH
if (safeSpaces.size() > 0)
resolveTurn(player, safeSpaces.get((int) (Math.random() * safeSpaces.size())));
else
resolveTurn(player, openSpaces.get((int) (Math.random() * openSpaces.size())));
break;
}
} else // If we've already peeked the space we rolled, let's just take it
{
resolveTurn(player, peekSpace);
}
} else
// Otherwise just pick a space
resolveTurn(player, safeSpaces.get((int) (Math.random() * safeSpaces.size())));
} else // Otherwise it sucks to be you, bot, eat bomb (or defuse bomb) (or failsafe)!
{
if (players.get(player).hiddenCommand == HiddenCommand.FAILSAFE) {
useFailsafe(player);
return;
}
int bombToPick = openSpaces.get((int) (Math.random() * openSpaces.size()));
if (players.get(player).hiddenCommand == HiddenCommand.DEFUSE)
useShuffler(player, bombToPick);
resolveTurn(player, bombToPick);
}
} else {
warnPlayer = timer.schedule(() -> {
// If they're out of the round somehow, why are we warning them?
if (players.get(player).status == PlayerStatus.ALIVE && gameStatus == GameStatus.IN_PROGRESS && player == currentTurn && !resolvingTurn) {
channel.sendMessage(players.get(player).getSafeMention() + ", thirty seconds left to choose a space!").queue();
displayBoardAndStatus(true, false, false);
}
}, 60, TimeUnit.SECONDS);
waiter.waitForEvent(MessageReceivedEvent.class, // Right player and channel
e -> {
if (players.get(player).status != PlayerStatus.ALIVE || gameStatus != GameStatus.IN_PROGRESS || player != currentTurn) {
return true;
} else if (e.getAuthor().equals(players.get(player).user) && e.getChannel().equals(channel) && checkValidNumber(e.getMessage().getContentStripped())) {
int location = Integer.parseInt(e.getMessage().getContentStripped());
try {
if (pickedSpaces[location - 1]) {
channel.sendMessage("That space has already been picked.").queue();
return false;
} else {
return true;
}
} catch (ArrayIndexOutOfBoundsException e1) {
return false;
}
}
return false;
}, // Parse it and call the method that does stuff
e -> {
warnPlayer.cancel(false);
// If they're somehow taking their turn when they're out of the round, just don't do anything
if (players.get(player).status == PlayerStatus.ALIVE && gameStatus == GameStatus.IN_PROGRESS && player == currentTurn) {
int location = Integer.parseInt(e.getMessage().getContentStripped()) - 1;
// Anyway go play out their turn
timer.schedule(() -> resolveTurn(player, location), 500, TimeUnit.MILLISECONDS);
}
}, 90, TimeUnit.SECONDS, () -> {
// If they're somehow taking their turn when they shouldn't be, just don't do anything
if (players.get(player).status == PlayerStatus.ALIVE && gameStatus == GameStatus.IN_PROGRESS && player == currentTurn && !resolvingTurn) {
timer.schedule(() -> timeOutTurn(player), 500, TimeUnit.MILLISECONDS);
}
});
}
}
use of tel.discord.rtab.board.SpaceType in project RtaB6 by Telnaior.
the class BonusCommand method execute.
@Override
protected void execute(CommandEvent event) {
for (GameController game : RaceToABillionBot.game) {
if (game.channel.equals(event.getChannel())) {
SpaceType desire;
switch(event.getArgs().toUpperCase()) {
case "CASH":
case "C":
case "MONEY":
case "M":
desire = SpaceType.CASH;
break;
case "BOOST":
case "BOOSTER":
case "B":
desire = SpaceType.BOOSTER;
break;
case "MINIGAME":
case "GAME":
case "G":
desire = SpaceType.GAME;
break;
case "EVENT":
case "E":
case "SPLIT AND SHARE":
desire = SpaceType.EVENT;
break;
case "BOMB":
event.reply("Well, if you say so.");
case "GRAB BAG":
case "BILLION":
case "ONE BILLION DOLLARS":
case "A BILLION DOLLARS":
case "A BILLION":
case "AMULET OF YENDOR":
case "THE AMULET OF YENDOR":
// greedy
desire = SpaceType.BOMB;
break;
// Useless memes follow
case "BLAMMO":
if (Math.random() < 0.5)
event.reply("Does this look like !blammo to you?");
else
event.reply("There are no blammos in the bonus bag.");
return;
case "NUMBERWANG":
case "NEGATIVE BILLION":
case "A NEGATIVE BILLION":
event.reply("You found **Numberwang**, worth shinty-six. Your score is unaffected.");
return;
case "TRIFORCE":
event.reply("You found **The Triforce**! " + "Click here to claim your prize: <https://www.youtube.com/watch?v=dQw4w9WgXcQ>");
return;
case "MEME":
event.reply("https://niceme.me");
return;
case "HIDDEN":
case "HIDDEN COMMAND":
case "A HIDDEN COMMAND":
event.reply("If you're using this command, you already have one.");
return;
case "BLESSED FIXED GREASED +2 GRAY DRAGON SCALE MAIL":
case "BLESSED FIXED GREASED +2 GREY DRAGON SCALE MAIL":
case "BLESSED FIXED GREASED +2 SILVER DRAGON SCALE MAIL":
event.reply("Unfortunately, nothing happens. (It's the bonus bag, not a wand of wishing)");
return;
default:
event.reply("Use !bonus cash, !bonus boost, !bonus game, or !bonus event to specify what you want.");
return;
}
int player = game.findPlayerInGame(event.getAuthor().getId());
// it's their turn, and they haven't picked a space) (this is getting a little silly)
if (game.gameStatus != GameStatus.IN_PROGRESS || player != game.currentTurn || game.resolvingTurn || game.currentBlammo || game.players.get(player).status != PlayerStatus.ALIVE || game.players.get(player).hiddenCommand != HiddenCommand.BONUS)
event.reply("You can't do this right now.");
else
game.useBonusBag(player, desire);
return;
}
}
// We aren't in a game channel? Uh...
event.reply("This is not a game channel.");
}
use of tel.discord.rtab.board.SpaceType in project RtaB6 by Telnaior.
the class GameController method usePeek.
public SpaceType usePeek(int playerID, int space) {
Player peeker = players.get(playerID);
peeker.peeks--;
if (playerID == currentTurn) {
peekStreak++;
if (peekStreak == 3)
Achievement.EXTRA_PEEKS.check(peeker);
}
SpaceType peekedSpace = gameboard.getType(space);
// If it's a bomb, add it to their known bombs
if (peekedSpace.isBomb())
peeker.knownBombs.add(space);
else
// Otherwise add it to their known safe spaces
peeker.safePeeks.add(space);
// If they're human, actually tell them what they won
if (!peeker.isBot) {
String peekClaim;
switch(peekedSpace) {
case CASH:
case BLAMMO:
peekClaim = "**CASH**";
break;
case GAME:
peekClaim = "a **MINIGAME**";
break;
case BOOSTER:
peekClaim = "a **BOOSTER**";
break;
case EVENT:
case GRAB_BAG:
peekClaim = "an **EVENT**";
break;
case BOMB:
case GB_BOMB:
peekClaim = "a **BOMB**";
break;
default:
peekClaim = "an **ERROR**";
break;
}
peeker.user.openPrivateChannel().queue((channel) -> channel.sendMessage(String.format("Space %d is %s.", space + 1, peekClaim)).queue());
}
return peekedSpace;
}
Aggregations