Created
December 19, 2012 02:36
-
-
Save TannerRogalsky/4333887 to your computer and use it in GitHub Desktop.
A bot to play cyberzone
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main; | |
import java.util.*; | |
import org.jibble.pircbot.*; | |
public class CyberBot extends PircBot { | |
boolean noGame = true, prep, inGame; | |
String chan = "#cyberzone"; | |
ArrayList<Player> players = new ArrayList<Player>(); | |
ArrayList<String> ops = new ArrayList<String>(); | |
int[][] board = null; // 2-15 represent items | |
int cur = 0; | |
int round = 0; | |
int itemUse = 0; | |
int deadLoop = -1; | |
int multiTrojan = 0; | |
String mbHack = ""; | |
String gameStarter = ""; | |
int config = 0; | |
int numItems = 0; | |
ArrayList<Integer> pickedItems = new ArrayList<Integer>(); | |
boolean handPicked; | |
int spawnInterval = 0; | |
int roundsUntilSpawn = 0; | |
int boardSize = 0; | |
// Set<Integer> itemsForDesc = new TreeSet<Integer>(); | |
Timer turnTimer; | |
String[] itemNames = new String[] { | |
"", "", "Trojan (Godhammer)", "ICE", "Backdoor", "Query", "Scan", "Overclock", "Cloak", "Phone phreak", "Reboot", | |
"Sector kill", "Invert", "Deadloop", "Defrag", "Magic Bullet", "White Knight", "tangerine.exe", "Magic Bullet ][", | |
"Silver Cord", "Trojan (Masquerade)", "Trojan (Monday Morning Massacre)", "Minesweeper", "dir.", "Torchbearer", | |
"Magic Bullet ]|[", "Flying Carpet" | |
}; | |
int[] itemProbs = new int[] { | |
0,0,8,5,5,6,5,3,6,3,3, // 0 - 10 | |
4,4,6,3,8,4,1,6, // 11 - 18 | |
3,7,7,2,5,3, // 19 - 24 | |
3,2 // 25 - | |
}; | |
int itemProbsLen = 0; | |
public static void main(String[] args) { | |
@SuppressWarnings("unused") | |
CyberBot bot = new CyberBot(); | |
} | |
public CyberBot() { | |
ops.add("thecalcgenius"); | |
ops.add("blue_tetris"); | |
for(int pr : itemProbs) | |
itemProbsLen += pr; | |
setMessageDelay(500); | |
setVerbose(true); | |
setName("CyberBot"); | |
setLogin("Cyberzone"); | |
setVersion("CyberBot by Calcy, v0.95; Game idea by blue_tetris"); | |
try { | |
connect("irc.waypasteleven.com"); | |
identify("pa55w0rd"); | |
setMode(getNick(), "+B"); | |
joinChannel(chan); | |
Thread.sleep(1000); | |
setTopic(chan, "Cyberzone | Type !start to begin. If the preparation for the game seems to be frozen, type !end. | About the game: http://metanet.2.forumer.com/index.php?showtopic=16812"); | |
} | |
catch (Exception ex) { | |
ex.printStackTrace(); | |
} | |
} | |
private void msg(String m) { | |
sendMessage(chan, m); | |
} | |
public void onMessage(String channel, String sender, String login, String hostname, String message) { | |
if(sender.equals("thecalcgenius")) { | |
if(message.equals("!verboseoff")) { | |
setVerbose(false); | |
} | |
else if(message.equals("!verboseon")) { | |
setVerbose(true); | |
} | |
else if(message.equals("!testprobs") && noGame) { | |
int[] times = new int[itemProbs.length]; | |
Random rnd = new Random(); | |
for(int i = 0; i < 1000; i++) { | |
int rndNum = rnd.nextInt(itemProbsLen); | |
int n, sum; | |
for(n = 2, sum = 0; n < itemProbs.length; n++) { | |
sum += itemProbs[n]; | |
if(rndNum < sum) break; | |
} | |
times[n]++; | |
} | |
msg("After 1000 iterations: "); | |
for(int i = 0; i < times.length; i++) { | |
msg(itemNames[i] + ": " + times[i]); | |
} | |
} | |
} | |
if(noGame && message.equals("!start")) { | |
noGame = false; | |
prep = true; | |
players = new ArrayList<Player>(); | |
// itemsForDesc = new TreeSet<Integer>(); | |
board = null; | |
cur = 0; | |
round = 0; | |
itemUse = 0; | |
deadLoop = -1; | |
gameStarter = sender; | |
turnTimer = new Timer("Prep timer"); | |
turnTimer.schedule(new TimerTask() { | |
public void run() { | |
endGame(); | |
} | |
}, 300000); | |
setMode(chan, "+N"); | |
msg(Colors.BLUE + "Grid active. Type \'jack\' to log into the mainframe. " + bold(sender) + ", once all hackers have " + | |
"jacked into the mainframe, type \'!load\' to boot the interface."); | |
} | |
else if((prep || config > 0) && (sender.equals(gameStarter) || ops.contains(sender)) && message.equals("!end")) { | |
endGame(); | |
} | |
else if(prep && message.equals("jack")) { | |
for(Player p : players) { | |
if(p.name.equals(sender)) { | |
sendNotice(sender, "You are already playing!"); | |
return; | |
} | |
} | |
if(players.size() == 12) { | |
msg(Colors.RED + "Sorry, 12 players maximum."); | |
return; | |
} | |
players.add(new Player(sender)); | |
voice(chan, sender); | |
msg(Colors.BLUE + bold(sender) + " jacks into the mainframe."); | |
} | |
else if(prep && message.equals("unjack")) { | |
int ind = findIndex(sender); | |
if(ind != -1) { | |
players.remove(ind); | |
deVoice(chan, sender); | |
msg(Colors.RED + bold(sender) + " unjacks himself from the mainframe."); | |
} | |
} | |
else if(prep && (sender.equals(gameStarter) || ops.contains(sender)) && message.equals("!config")) { | |
if(players.size() < 2) { | |
msg(Colors.RED + "2 or more hackers required to configure and load interface."); | |
return; | |
} | |
turnTimer.cancel(); | |
config = 1; | |
prep = false; | |
// DELETE | |
msg(Colors.DARK_GREEN + bold(gameStarter) + " edits \"config.ini\"."); | |
msg(Colors.DARK_GREEN + bold(gameStarter) + ", enter the length of the board you wish to play on. The length can be " + | |
"any number from " + (players.size()+1) + " to 20, inclusive. Type \"default\" to select the default value."); | |
//config = 0; | |
} | |
else if((sender.equals(gameStarter) || ops.contains(sender)) && config > 0 && config != 100) { | |
configure(message); | |
return; | |
} | |
else if((prep || config == 100) && (sender.equals(gameStarter) || ops.contains(sender)) && message.equals("!load")) { | |
//msg("config finished, loading interface..."); | |
if(players.size() < 2) { | |
msg(Colors.RED + "2 or more hackers required to load interface."); | |
return; | |
} | |
prep = false; | |
inGame = true; | |
turnTimer.cancel(); | |
//numItems = 0; | |
//pickedItems = new ArrayList<Integer>(); | |
//handpicked | |
//spawnInterval = 0; | |
//boardSize = 0; | |
if(config == 0) { | |
boardSize = 4+players.size()+(players.size()/3); | |
numItems = boardSize - players.size(); | |
spawnInterval = 2 + players.size(); | |
// msg("if statement on line 182 reached, shouldn\'t happen"); | |
} | |
roundsUntilSpawn = spawnInterval; | |
config = 0; | |
setTopic(chan, "Cyberzone | Game in progress. | About the game: http://metanet.2.forumer.com/index.php?showtopic=16812"); | |
board = new int[boardSize][boardSize]; | |
ArrayList<Integer> rows = new ArrayList<Integer>(), cols = new ArrayList<Integer>(); | |
ArrayList<String> names = new ArrayList<String>(); | |
for(int i = 0; i < board.length; i++) { | |
rows.add(i); | |
cols.add(i); | |
} | |
Random rnd = new Random(); | |
for(Player p : players) { | |
int r = rows.remove(rnd.nextInt(rows.size())); | |
int c = cols.remove(rnd.nextInt(cols.size())); | |
board[r][c] = 1; | |
p.r = r; | |
p.c = c; | |
} | |
boolean calcPlay = false; | |
for(Player p : players) | |
if(p.name.equals("thecalcgenius")) | |
calcPlay = true; | |
for(int i = 0; i < numItems; i++) { | |
int r = rows.remove(rnd.nextInt(rows.size())); | |
int c = cols.remove(rnd.nextInt(cols.size())); | |
int rndNum = rnd.nextInt(itemProbsLen); | |
int n, sum; | |
for(n = 2, sum = 0; n < itemProbs.length; n++) { | |
sum += itemProbs[n]; | |
if(rndNum < sum) break; | |
} | |
board[r][c] = n; | |
names.add(itemNames[n]); | |
//if(!calcPlay) sendMessage("thecalcgenius", itemNames[n] + " is at " + ((char)(r+65)) + "" + (c+1)); | |
} | |
for(int i = 0; i < 7; i++) Collections.shuffle(players); | |
msg(Colors.BLUE + "Interface online. Hacker avatars have been uploaded to the mainframe."); | |
String temp = ""; | |
for(Player p : players) { | |
temp += " " + p.name; | |
} | |
msg(Colors.BLUE + "Grid size is " + board.length + "x" + board.length + "."); | |
msg(Colors.BLUE + "The hacker order will be:" + temp); | |
Collections.sort(names); | |
if(!names.isEmpty()) msg(Colors.DARK_GREEN + "Programs loaded: " + names.toString()); | |
//msg(Colors.BLUE + "PM \"!desc\" to me for detailed descriptions of the programs in the mainframe."); | |
giveInfo(); | |
} | |
else if(inGame && ops.contains(sender) && message.startsWith("!eject ") && itemUse == 0) { | |
String name = message.split(" ")[1]; | |
int ind; | |
if((ind = findIndex(name)) != -1) { | |
if(ind == cur) { | |
players.remove(ind); | |
deVoice(chan, name); | |
msg(Colors.RED + bold(name) + " has been forcibly ejected from the mainframe. His space will not be holed."); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
giveInfo(); | |
} | |
else { | |
players.remove(ind); | |
deVoice(chan, name); | |
msg(Colors.RED + bold(name) + " has been forcibly ejected from the mainframe. His space will not be holed."); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
if(ind < cur) cur--; | |
} | |
} | |
else { | |
msg(Colors.RED + bold(name) + " is not a part of this game."); | |
} | |
} | |
else if(inGame && sender.equals(players.get(cur).name) && itemUse != 4 && itemUse != 20 && itemUse != 21) { | |
if(itemUse == 2) { | |
if(!validSpace(message,1)) { | |
msg(Colors.DARK_GREEN + "FAT32 error. Node inaccessible. Input a different move."); | |
return; | |
} | |
int rr = message.charAt(0) - 65, cc = Integer.parseInt(message.substring(1))-1; | |
if(board[rr][cc] == 1) { | |
board[rr][cc] = -1; | |
itemUse = 0; | |
testHack(rr, cc, sender); | |
return; | |
} | |
board[rr][cc] = -1; | |
} | |
else if(itemUse == 5) { | |
if(sender.equalsIgnoreCase("message")) { | |
msg(Colors.DARK_GREEN + "Probable recursion has forced a program abort. Query a non-host avatar."); | |
return; | |
} | |
Player p; | |
if((p = nameExists(message)) == null) { | |
msg(Colors.DARK_GREEN + "Avatar not found. Query an avatar within the database."); | |
return; | |
} | |
sendMessage(sender, p.name + " is located at " + p.loc() + "."); | |
} | |
else if(itemUse == 6) { | |
if(!validSpace(message,0)) { | |
msg(Colors.DARK_GREEN + "FAT32 error. Node inaccessible. Input a different move."); | |
return; | |
} | |
int rr = message.charAt(0) - 65, cc = Integer.parseInt(message.substring(1))-1; | |
sendMessage(sender, "At " + message + ": " + giveInfo2(rr, cc, 1)); | |
} | |
else if(itemUse == 9) { | |
if(!validSpace(message,0)) { | |
msg(Colors.DARK_GREEN + "FAT32 error. Node inaccessible. Input a different move."); | |
return; | |
} | |
int rr = message.charAt(0) - 65, cc = Integer.parseInt(message.substring(1))-1; | |
if(board[rr][cc] == 0) | |
board[rr][cc] = -1; | |
multiTrojan--; | |
if(multiTrojan > 0) { | |
msg(Colors.DARK_GREEN + multiTrojan + " left."); | |
return; | |
} | |
} | |
else if(itemUse == 10) { | |
if(!validRC(message)) { | |
msg(Colors.DARK_GREEN + "Target sector does not meet core criterion. Select a different row or column."); | |
return; | |
} | |
if(Character.isUpperCase(message.charAt(0))) { | |
int rr = message.charAt(0)-65; | |
for(int c = 0; c < board.length; c++) { | |
if(board[rr][c] == -1) | |
board[rr][c] = 0; | |
} | |
} | |
else { | |
int cc = Integer.parseInt(message) - 1; | |
for(int r = 0; r < board.length; r++) { | |
if(board[r][cc] == -1) | |
board[r][cc] = 0; | |
} | |
} | |
} | |
else if(itemUse == 11) { | |
if(!validRC(message)) { | |
msg(Colors.DARK_GREEN + "Target sector does not meet core criterion. Select a different row or column."); | |
return; | |
} | |
if(Character.isUpperCase(message.charAt(0))) { | |
int rr = message.charAt(0)-65; | |
for(int c = 0; c < board.length; c++) { | |
if(board[rr][c] != 1) | |
board[rr][c] = -1; | |
} | |
} | |
else { | |
int cc = Integer.parseInt(message) - 1; | |
for(int r = 0; r < board.length; r++) { | |
if(board[r][cc] != 1) | |
board[r][cc] = -1; | |
} | |
} | |
} | |
else if(itemUse == 12) { | |
if(!validRC(message)) { | |
msg(Colors.DARK_GREEN + "Target sector does not meet core criterion. Select a different row or column."); | |
return; | |
} | |
if(Character.isUpperCase(message.charAt(0))) { | |
int rr = message.charAt(0)-65; | |
for(int c = 0; c < board.length; c++) { | |
if(board[rr][c] == -1) | |
board[rr][c] = 0; | |
else if(board[rr][c] == 0) | |
board[rr][c] = -1; | |
} | |
} | |
else { | |
int cc = Integer.parseInt(message) - 1; | |
for(int r = 0; r < board.length; r++) { | |
if(board[r][cc] == -1) | |
board[r][cc] = 0; | |
else if(board[r][cc] == 0) | |
board[r][cc] = -1; | |
} | |
} | |
} | |
else if(itemUse == 15) { | |
if(!(message.equalsIgnoreCase("r") || message.equalsIgnoreCase("c") || message.equalsIgnoreCase("row") || | |
message.equalsIgnoreCase("column"))) { | |
msg(Colors.DARK_GREEN + "Invalid input string. State row " + bold("(R)") + " or column " + | |
bold("(C)") + "."); | |
return; | |
} | |
Player p = players.get(cur); | |
if(message.equalsIgnoreCase("r") || message.equalsIgnoreCase("row")) { | |
int rr = p.r; | |
for(int c = 0; c < board.length; c++) { | |
if(c == p.c) continue; | |
if(board[rr][c] == 1) { | |
board[rr][c] = -1; | |
int ind = findIndex(rr, c); | |
Player np = players.get(ind); | |
msg(Colors.RED + bold(p.name) + " uploads magic bullet program to " + bold(np.name) + "\'s avatar. " + | |
bold(np.name) + " is forced to hard reboot, and drops from the mainframe!"); | |
deVoice(chan, np.name); | |
players.remove(ind); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
if(ind < cur) cur--; | |
} | |
} | |
} | |
else { | |
int cc = p.c; | |
for(int r = 0; r < board.length; r++) { | |
if(r == p.r) continue; | |
if(board[r][cc] == 1) { | |
board[r][cc] = -1; | |
int ind = findIndex(r, cc); | |
Player np = players.get(ind); | |
msg(Colors.RED + bold(p.name) + " uploads magic bullet program to " + bold(np.name) + "\'s avatar. " + | |
bold(np.name) + " is forced to hard reboot, and drops from the mainframe!"); | |
deVoice(chan, np.name); | |
players.remove(ind); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
if(ind < cur) cur--; | |
} | |
} | |
} | |
if(cur < 0) cur += players.size(); | |
} | |
else if(itemUse == 18) { | |
if(mbHack.equals("")) { | |
if(sender.equalsIgnoreCase(message)) { | |
msg(Colors.DARK_GREEN + "Probable recursion has forced a program abort. Query a non-host avatar."); | |
return; | |
} | |
if(nameExists(message) == null) { | |
msg(Colors.DARK_GREEN + "Avatar not found. Query an avatar within the database."); | |
return; | |
} | |
mbHack = message; | |
msg(Colors.DARK_GREEN + "Now, enter a specific name of a row (A-" + ((char)(board.length+64)) + ") or a column " + | |
"(1-" + (board.length) + "). If the hacker\'s avatar is located within that row or column, he will " + | |
"be ejected from the mainframe."); | |
return; | |
} | |
else { | |
if(!validRC(message)) { | |
msg(Colors.DARK_GREEN + "Target sector does not meet core criterion. Select a different row or column."); | |
return; | |
} | |
int ind = findIndex(mbHack); | |
Player np = players.get(ind); | |
mbHack = ""; | |
if(Character.isUpperCase(message.charAt(0))) { | |
int rr = message.charAt(0)-65; | |
if(np.r == rr) { | |
Player p = players.get(cur); | |
msg(Colors.RED + bold(p.name) + " uploads \"Jade Lightning\" to " + bold(np.name) + "\'s avatar. " + | |
bold(np.name) + " is forced to hard reboot, and drops from the mainframe!"); | |
deVoice(chan, np.name); | |
players.remove(ind); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
if(ind < cur) cur--; | |
} | |
} | |
else { | |
int cc = Integer.parseInt(message) - 1; | |
//msg(bold("cc = " + cc)); | |
if(np.c == cc) { | |
Player p = players.get(cur); | |
msg(Colors.RED + bold(p.name) + " uploads \"Jade Lightning\" to " + bold(np.name) + "\'s avatar. " + | |
bold(np.name) + " is forced to hard reboot, and drops from the mainframe!"); | |
deVoice(chan, np.name); | |
players.remove(ind); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
if(ind < cur) cur--; | |
} | |
} | |
} | |
} | |
else if(itemUse == 22) { | |
if(!validSpace(message,0)) { | |
msg(Colors.DARK_GREEN + "FAT32 error. Node inaccessible. Input a different move."); | |
return; | |
} | |
int rr = message.charAt(0) - 65, cc = Integer.parseInt(message.substring(1))-1; | |
if(board[rr][cc] == -1) | |
board[rr][cc] = 0; | |
multiTrojan--; | |
if(multiTrojan > 0) { | |
msg(Colors.DARK_GREEN + multiTrojan + " left."); | |
return; | |
} | |
} | |
else if(itemUse == 23) { | |
if(!validRC(message)) { | |
msg(Colors.DARK_GREEN + "Target sector does not meet core criterion. Select a different row or column."); | |
return; | |
} | |
if(Character.isUpperCase(message.charAt(0))) { | |
int rr = message.charAt(0)-65; | |
String s = "Holes in row " + message.charAt(0) + ":"; | |
for(int c = 0; c < board.length; c++) | |
if(board[rr][c] == -1) | |
s += " " + ((char)(rr+65)) + (c+1) + ","; | |
if(s.endsWith(":")) | |
sendMessage(sender, "No holes in row " + message.charAt(0) + "."); | |
else | |
sendMessage(sender, s.substring(0, s.length() - 1) + "."); | |
} | |
else { | |
int cc = Integer.parseInt(message) - 1; | |
String s = "Holes in column " + (cc+1) + ":"; | |
for(int r = 0; r < board.length; r++) | |
if(board[r][cc] == -1) | |
s += " " + ((char)(r+65)) + (cc+1) + ","; | |
if(s.endsWith(":")) | |
sendMessage(sender, "No holes in column " + (cc+1) + "."); | |
else | |
sendMessage(sender, s.substring(0, s.length() - 1) + "."); | |
} | |
} | |
else if(itemUse == 24) { | |
if(!(message.equalsIgnoreCase("r") || message.equalsIgnoreCase("c") || message.equalsIgnoreCase("row") || | |
message.equalsIgnoreCase("column"))) { | |
msg(Colors.DARK_GREEN + "Invalid input string. State row " + bold("(R)") + " or column " + | |
bold("(C)") + "."); | |
return; | |
} | |
msg(Colors.DARK_GREEN + "Uploading info..."); | |
if(message.equalsIgnoreCase("r") || message.equalsIgnoreCase("row")) { | |
for(int r = 0; r < board.length; r++) | |
sendMessage(sender, giveInfoR(r, 0, 1)); | |
} | |
else { | |
for(int c = 0; c < board.length; c++) | |
sendMessage(sender, giveInfoC(0, c, 1)); | |
} | |
} | |
else if(itemUse == 25) { | |
if(!validSpace(message,0)) { | |
msg(Colors.DARK_GREEN + "FAT32 error. Node inaccessible. Input a different move."); | |
return; | |
} | |
//msg("25. input accepted. cur = " + cur); | |
boolean found = false; | |
int rr = message.charAt(0) - 65, cc = Integer.parseInt(message.substring(1))-1; | |
Player p = players.get(cur); | |
for(int c = 0; c < board.length; c++) { | |
if(board[rr][c] == 1) { | |
int ind = findIndex(rr, c); | |
if(cur == ind) continue; | |
//msg("victim found in 1. cur = " + cur); | |
found = true; | |
board[rr][c] = 0; | |
Player np = players.get(ind); | |
msg(Colors.RED + bold(p.name) + " rides the bomb onto " + bold(np.name) + "\'s avatar. " + bold(np.name) + | |
" stops worrying and hard reboots."); | |
msg(Colors.RED + bold(np.name) + " drops from the mainframe!"); | |
deVoice(chan, np.name); | |
players.remove(ind); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
if(ind < cur) cur--; | |
//msg("victim dead, player removed. cur = " + cur); | |
} | |
} | |
for(int r = 0; r < board.length; r++) { | |
if(board[r][cc] == 1) { | |
int ind = findIndex(r,cc); | |
if(cur == ind) continue; | |
//msg("victim found in 2. cur = " + cur); | |
found = true; | |
board[r][cc] = 0; | |
Player np = players.get(ind); | |
msg(Colors.RED + bold(p.name) + " rides the bomb onto " + bold(np.name) + "\'s avatar. " + bold(np.name) + | |
" stops worrying and hard reboots."); | |
msg(Colors.RED + bold(np.name) + " drops from the mainframe!"); | |
deVoice(chan, np.name); | |
players.remove(ind); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
if(ind < cur) cur--; | |
//msg("victim dead, player removed. cur = " + cur); | |
} | |
} | |
//msg("all victims dead. now moving player. cur = " + cur); | |
if(found) { | |
board[p.r][p.c] = 0; | |
p.r = rr; | |
p.c = cc; | |
itemUse = 0; | |
if(board[rr][cc] == 1) { | |
testHack(rr, cc, sender); | |
return; | |
} | |
if(board[rr][cc] > 1) { | |
informItem(p, rr, cc, sender); | |
return; | |
} | |
board[p.r][p.c] = 1; | |
cur++; | |
cur = cur % players.size(); | |
giveInfo(); | |
return; | |
} | |
else { | |
board[p.r][p.c] = 0; | |
msg(Colors.RED + bold(sender) + " is reported to SysOps, and drops from the mainframe."); | |
deVoice(chan, sender); | |
players.remove(cur); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
cur--; | |
} | |
//msg("25 done. cur = " + cur); | |
} | |
if(itemUse != 0) { | |
itemUse = 0; | |
cur++; | |
cur = cur % players.size(); | |
giveInfo(); | |
} | |
} | |
} | |
private void endGame() { | |
prep = false; | |
config = 0; | |
noGame = true; | |
msg(Colors.RED + "Grid deactivated."); | |
for(Player p : players) { | |
deVoice(chan, p.name); | |
} | |
setMode(chan, "-N"); | |
} | |
private void configure(String message) { | |
if(config == 1) { | |
try { | |
int n = Integer.parseInt(message); | |
if(n <= players.size() || n > 20) { | |
msg(Colors.DARK_GREEN + "Invalid board size."); | |
return; | |
} | |
boardSize = n; | |
msg(Colors.DARK_GREEN + "Now, enter the number of programs to initially place on the board. You can have between " + | |
"0 and " + (boardSize-players.size()) + " programs, inclusive. Type \"default\" for the default setting."); | |
config = 2; | |
} catch(Exception ex) { | |
if(message.equalsIgnoreCase("default")) { | |
boardSize = 4 + players.size() + (players.size()/3); | |
msg(Colors.DARK_GREEN + "Now, enter the number of programs to initially place on the board. You can have between " + | |
"0 and " + (boardSize-players.size()) + " programs, inclusive. Type \"default\" for the default setting."); | |
config = 2; | |
} | |
else | |
msg(Colors.DARK_GREEN + "Invalid entry."); | |
return; | |
} | |
} | |
else if(config == 2) { | |
try { | |
int n = Integer.parseInt(message); | |
if(n < 0 || (n > boardSize-players.size())) { | |
msg(Colors.DARK_GREEN + "Invalid amount."); | |
return; | |
} | |
numItems = n; | |
if(numItems > 0) { | |
msg(Colors.DARK_GREEN + "Do you want to pick what programs show up on the board yourself? Answer \"yes\" or " + | |
"\"no\". If you choose not to pick, random programs will be loaded."); | |
config = 3; | |
} | |
else { | |
msg(Colors.DARK_GREEN + "Enter the number of rounds to wait before loading a new program into the mainframe. " + | |
"Minimum is 2. Type \"none\" to eliminate spawning of items. Type \"default\" for the default setting."); | |
config = 5; | |
} | |
} catch(Exception ex) { | |
if(message.equalsIgnoreCase("default")) { | |
numItems = boardSize - players.size(); | |
msg(Colors.DARK_GREEN + "Do you want to pick what programs show up on the board yourself? Answer \"yes\" or " + | |
"\"no\". If you choose not to pick, random programs will be loaded."); | |
config = 3; | |
} | |
else | |
msg(Colors.DARK_GREEN + "Invalid entry."); | |
return; | |
} | |
// msg(Colors.DARK_GREEN + "Congratulations! The mainframe has been succesfully configured. Type \"!load\" to activate " + | |
// "the grid."); | |
// config = 100; | |
} | |
else if(config == 3) { | |
if(message.equalsIgnoreCase("y") || message.equalsIgnoreCase("yes")) { | |
msg(Colors.DARK_GREEN + "It\'s not implemented yet. Type no."); | |
} | |
else if(message.equalsIgnoreCase("n") || message.equalsIgnoreCase("no")) { | |
msg(Colors.DARK_GREEN + "Enter the number of rounds to wait before loading a new program into the mainframe. " + | |
"Minimum is 2. Type \"none\" to eliminate spawning of items. Type \"default\" for the default setting."); | |
config = 5; | |
} | |
} | |
else if(config == 4) { | |
} | |
else if(config == 5) { | |
try { | |
int n = Integer.parseInt(message); | |
if(n < 2) { | |
msg(Colors.DARK_GREEN + "Invalid amount."); | |
return; | |
} | |
spawnInterval = n; | |
msg(Colors.DARK_GREEN + "Enter any permanent items you wish to have at the start of the game. Choices are \"ICE\", " + | |
"\"Cloak\", \"WK\" (White Knight), \"SC\" (Silver Cord), \"FC\" (Flying Carpet), or any combination of " + | |
"these (enter each one separately). Once you are finished entering the combination of items, or if you " + | |
"do not want any initial items, type \"done\"."); | |
config = 6; | |
} catch(Exception ex) { | |
if(message.equalsIgnoreCase("default")) { | |
spawnInterval = 2 + players.size(); | |
msg(Colors.DARK_GREEN + "Enter any permanent items you wish to have at the start of the game. Choices are \"ICE\", " + | |
"\"Cloak\", \"WK\" (White Knight), \"SC\" (Silver Cord), \"FC\" (Flying Carpet), or any combination of " + | |
"these (enter each one separately). Once you are finished entering the combination of items, or if you " + | |
"do not want any initial items, type \"done\"."); | |
config = 6; | |
} | |
else if(message.equalsIgnoreCase("none")) { | |
spawnInterval = -1; | |
msg(Colors.DARK_GREEN + "Enter any permanent items you wish to have at the start of the game. Choices are \"ICE\", " + | |
"\"Cloak\", \"WK\" (White Knight), \"SC\" (Silver Cord), \"FC\" (Flying Carpet), or any combination of " + | |
"these (enter each one separately). Once you are finished entering the combination of items, or if you " + | |
"do not want any initial items, type \"done\"."); | |
config = 6; | |
} | |
else | |
msg(Colors.DARK_GREEN + "Invalid entry."); | |
return; | |
} | |
} | |
else if(config == 6) { | |
if(message.equalsIgnoreCase("ice")) { | |
for(Player p : players) | |
p.ice = true; | |
msg(Colors.DARK_GREEN + "ICE has been loaded."); | |
} | |
else if(message.equalsIgnoreCase("cloak")) { | |
for(Player p : players) | |
p.cloak = true; | |
msg(Colors.DARK_GREEN + "The Cloak program has been loaded."); | |
} | |
else if(message.equalsIgnoreCase("wk")) { | |
for(Player p : players) | |
p.knight = true; | |
msg(Colors.DARK_GREEN + "The White Knight (tm) program has been loaded."); | |
} | |
else if(message.equalsIgnoreCase("sc")) { | |
for(Player p : players) | |
p.cord = true; | |
msg(Colors.DARK_GREEN + "The Silver Cord has been loaded."); | |
} | |
else if(message.equalsIgnoreCase("fc")) { | |
for(Player p : players) | |
p.carpet = true; | |
msg(Colors.DARK_GREEN + "The Flying Carpet has been loaded."); | |
} | |
else if(message.equalsIgnoreCase("done")) { | |
msg(Colors.DARK_GREEN + "Congratulations! The mainframe has been succesfully configured. Type \"!load\" to activate " + | |
"the grid."); | |
config = 100; | |
// msg("boardSize = " + boardSize); | |
// msg("numItems = " + numItems); | |
// msg("spawnInt = " + spawnInterval); | |
} | |
} | |
} | |
private void win(String name) { | |
turnTimer.cancel(); | |
msg(Colors.BLUE + bold(name) + " now has uncontested domain over the mainframe!"); | |
msg(Colors.BLUE + "Good game."); | |
setMode(chan, "-N"); | |
setTopic(chan, "Cyberzone | Type !start to begin. If the preparation for the game seems to be frozen, type !end. | About the game: http://metanet.2.forumer.com/index.php?showtopic=16812"); | |
deVoice(chan, name); | |
noGame = true; | |
inGame = false; | |
config = 0; | |
return; | |
} | |
private String bold(String n) { | |
return Colors.BOLD + n + Colors.BOLD; | |
} | |
private boolean validRC(String message) { | |
try { | |
int c = Integer.parseInt(message) - 1; | |
return c >= 0 && c < board.length; | |
} catch(Exception ex) { | |
if(message.length() != 1 || !Character.isUpperCase(message.charAt(0))) | |
return false; | |
char r = message.charAt(0); | |
return r >= 'A' && r < board.length + 65; | |
} | |
} | |
private int findIndex(int r, int c) { | |
for(int i = 0; i < players.size(); i++) { | |
Player pl = players.get(i); | |
if(pl.r == r && pl.c == c) | |
return i; | |
} | |
return -1; | |
} | |
private int findIndex(String message) { | |
for(int i = 0; i < players.size(); i++) { | |
if(players.get(i).name.equalsIgnoreCase(message)) | |
return i; | |
} | |
return -1; | |
} | |
private Player nameExists(String message) { | |
for(Player p : players) { | |
if(p.name.equalsIgnoreCase(message)) | |
return p; | |
} | |
return null; | |
} | |
private boolean validSpace(String msg, int eq) { // EQ = 1 IF CHECKING IS REQUIRED | |
if(msg.length() < 2 || !Character.isUpperCase(msg.charAt(0))) { | |
return false; | |
} | |
int rr, cc; | |
try { | |
cc = Integer.parseInt(msg.substring(1))-1; | |
}catch(Exception ex) { | |
return false; | |
} | |
rr = msg.charAt(0) - 65; | |
Player p = players.get(cur); | |
if(rr < 0 || rr >= board.length || cc < 0 || cc >= board.length) { | |
return false; | |
} | |
if(eq == 1 && p.r == rr && p.c == cc) | |
return false; | |
return true; | |
} | |
public void onPrivateMessage(String sender, String login, String hostname, String message) { | |
turnTimer.cancel(); | |
if(inGame && sender.equals(players.get(cur).name)) { | |
if(itemUse == 4 || itemUse == 20 || itemUse == 21) { | |
if(itemUse == 4) { | |
if(!validSpace(message,0)) { | |
sendMessage(sender, Colors.DARK_GREEN + bold(sender) + " Invalid location. Please choose " + | |
"another space."); | |
return; | |
} | |
Player p = players.get(cur); | |
int rr = message.charAt(0) - 65, cc = Integer.parseInt(message.substring(1))-1; | |
p.r = rr; | |
p.c = cc; | |
itemUse = 0; | |
if(board[rr][cc] == 1) { | |
testHack(rr, cc, sender); | |
return; | |
} | |
if(board[rr][cc] > 1) { | |
informItem(p, rr, cc, sender); | |
return; | |
} | |
board[p.r][p.c] = 1; | |
} | |
else if(itemUse == 20) { | |
if(!validSpace(message,1)) { | |
sendMessage(sender, "Invalid location. Please choose another space."); | |
return; | |
} | |
Player p = players.get(cur); | |
int rr = message.charAt(0) - 65, cc = Integer.parseInt(message.substring(1))-1; | |
if(p.r != rr && p.c != cc) { | |
sendMessage(sender, "The location must be in your row or column!"); | |
return; | |
} | |
if(board[rr][cc] == 1) { | |
board[rr][cc] = -1; | |
itemUse = 0; | |
testHack(rr, cc, sender); | |
return; | |
} | |
board[rr][cc] = -1; | |
} | |
else if(itemUse == 21) { | |
if(!validSpace(message,1)) { | |
sendMessage(sender, "Invalid location. Please choose another space."); | |
return; | |
} | |
int rr = message.charAt(0) - 65, cc = Integer.parseInt(message.substring(1))-1; | |
if(board[rr][cc] == 1) { | |
board[rr][cc] = -1; | |
itemUse = 0; | |
testHack(rr, cc, sender); | |
return; | |
} | |
board[rr][cc] = -1; | |
} | |
itemUse = 0; | |
cur++; | |
cur = cur % players.size(); | |
giveInfo(); | |
} | |
else if(itemUse == 0){ | |
if(!validSpace(message,1)) { | |
sendMessage(sender, "Invalid location. Please enter another space."); | |
return; | |
} | |
Player p = players.get(cur); | |
int rr = message.charAt(0) - 65, cc = Integer.parseInt(message.substring(1))-1; | |
if(p.r != rr && p.c != cc && !p.knight) { | |
sendMessage(sender, "The location must be in your row or column!"); | |
return; | |
} | |
board[p.r][p.c] = -1; | |
if(board[rr][cc] == -1) { | |
p.r = rr; | |
p.c = cc; | |
if(p.cord) { | |
msg(Colors.DARK_GREEN + bold(sender) + " slips through a hole in the mainframe, but is lifted out by The " + | |
"Silver Cord. The Silver Cord is broken."); | |
board[rr][cc] = 1; | |
p.cord = false; | |
cur++; | |
} | |
else if(p.carpet) { | |
msg(Colors.DARK_GREEN + bold(sender) + " invokes the power of the Flying Carpet to soar over a hole at " + | |
p.loc() + "."); | |
board[rr][cc] = 1; | |
cur++; | |
} | |
else { | |
msg(Colors.RED + bold(sender) + " slips through the hole " + p.loc() + ", and loses all user access. " + | |
bold(sender) + " drops from the mainframe!"); | |
deVoice(chan, sender); | |
players.remove(cur); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
} | |
cur = cur % players.size(); | |
giveInfo(); | |
return; | |
} | |
p.r = rr; | |
p.c = cc; | |
if(board[rr][cc] == 1) { | |
testHack(rr, cc, sender); | |
return; | |
} | |
if(board[rr][cc] > 1) { | |
informItem(p, rr, cc, sender); | |
return; | |
} | |
board[p.r][p.c] = 1; | |
cur++; | |
cur = cur % players.size(); | |
giveInfo(); | |
} | |
} | |
} | |
/*private void testHack2(int rr, int cc, int ind) { | |
Player p = players.get(ind); | |
for(int i = 0; i < players.size(); i++) { | |
if(i == cur) continue; | |
Player np = players.get(i); | |
if(np.r == rr && np.c == cc) { | |
if(np.ice) { | |
msg(Colors.RED + bold(p.name) + " hacks " + bold(np.name) + "\'s avatar. " + bold(np.name) + " executes ICE, " + | |
"preventing the hack. " + bold(p.name) + " is revealed to SysOps and is forcibly ejected from the " + | |
"mainframe!"); | |
deVoice(chan, p.name); | |
players.remove(cur); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
cur = cur % players.size(); | |
giveInfo(); | |
return; | |
} | |
else { | |
msg(Colors.RED + bold(p.name) + " hacks " + bold(np.name) + "\'s avatar. " + bold(np.name) + " drops from the " + | |
"mainframe!"); | |
deVoice(chan, np.name); | |
players.remove(i); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
if(i > cur) cur++; | |
cur = cur % players.size(); | |
giveInfo(); | |
return; | |
} | |
} | |
} | |
msg("Something failed when " + p.name + " tried to take over the spot at " + rr + " " + cc); | |
} | |
*/ | |
private void testHack(int rr, int cc, String sender) { | |
for(int i = 0; i < players.size(); i++) { | |
if(i == cur) continue; | |
Player np = players.get(i); | |
if(np.r == rr && np.c == cc) { | |
if(np.ice) { | |
msg(Colors.RED + bold(sender) + " hacks " + bold(np.name) + "\'s avatar at " + np.loc() + ". " + bold(np.name) + | |
" executes ICE, preventing the hack. " + bold(sender) + " is revealed to SysOps and is forcibly ejected " + | |
"from the mainframe!"); | |
deVoice(chan, sender); | |
players.remove(cur); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
cur = cur % players.size(); | |
giveInfo(); | |
return; | |
} | |
else { | |
msg(Colors.RED + bold(sender) + " hacks " + bold(np.name) + "\'s avatar at " + np.loc() + ". " + bold(np.name) + | |
" drops from the mainframe!"); | |
deVoice(chan, np.name); | |
players.remove(i); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
if(i > cur) cur++; | |
cur = cur % players.size(); | |
giveInfo(); | |
return; | |
} | |
} | |
} | |
//msg("Something failed when " + sender + " tried to take over the spot at " + rr + " " + cc); | |
} | |
private void informItem(Player p, int rr, int cc, String sender) { | |
if(board[rr][cc] == 2) { | |
itemUse = 2; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes the Trojan virus, GodHammer Edition."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", input the name of a space publically. The space you name will be holed. If " + | |
"an avatar or item is in that space, it slips from the mainframe."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 3) { | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and installs Intrustion Counter-Electronics. " + bold(sender) + | |
" cannot be hacked. Avatars hacking " + bold(sender) + " will instead be revealed to system operators and " + | |
"ejected from the mainframe."); | |
p.ice = true; | |
} | |
else if(board[rr][cc] == 4) { | |
itemUse = 4; | |
msg(Colors.DARK_GREEN + bold(sender) + " locates a backdoor in the mainframe."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", using PM, input the name of a space. Your avatar will be relocated to the " + | |
"space you input. If this space is holed, the hole will be removed and your avatar will land safely. If this " + | |
"space contains an avatar, you hack them. If this space contains a program, you instantly run that program. The " + | |
"space where you originated from will be holed."); | |
board[p.r][p.c] = -1; | |
return; | |
} | |
else if(board[rr][cc] == 5) { | |
itemUse = 5; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes a query relay."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", input the name of a hacker publically. The query will privately reveal the " + | |
"exact location of that hacker's avatar. " + Colors.BOLD + "Hacker names are case-sensitive."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 6) { | |
itemUse = 6; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes a scan relay."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", input the name of a space publically. The scan will retrieve information for " + | |
"you as if you were in that space. The information will arrive privately."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 7) { | |
msg(Colors.DARK_GREEN + bold(sender) + " overclocks the deck, and immediately takes another turn."); | |
board[p.r][p.c] = 1; | |
giveInfo3(); | |
return; | |
} | |
else if(board[rr][cc] == 8) { | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and installs a cloaking program, and is now invisible to normal " + | |
"detection."); | |
p.cloak = true; | |
} | |
else if(board[rr][cc] == 9) { | |
itemUse = 9; | |
multiTrojan = board.length; | |
msg(Colors.DARK_GREEN + bold(sender) + " finds an insecure port to phone phreak the mainframe."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", enter " + board.length + " spaces, one by one. Each space you type will be " + | |
"holed unless there is an avatar or an item in that space."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 10) { | |
itemUse = 10; | |
msg(Colors.DARK_GREEN + bold(sender) + " finds a gap in code, allowing for a safe reboot."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", publically input the name of a row (A-" + | |
((char)(board.length+64)) + ") or a column (1-" + (board.length) + "). The holes in that sector will become " + | |
"free grid spaces again."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 11) { | |
itemUse = 11; | |
msg(Colors.DARK_GREEN + bold(sender) + " finds a gap in code, allowing for a potent sector kill."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", publically input the name of a row (A-" + | |
((char)(board.length+64)) + ") or a column (1-" + (board.length) + "). The free spaces in this sector become " + | |
"holes. Any program on a space in this sector is dropped from the mainframe. Avatar spaces are not " + | |
"affected."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 12) { | |
itemUse = 12; | |
msg(Colors.DARK_GREEN + bold(sender) + " finds a gap in code, allowing for a strategic inversion."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", publically input the name of a row (A-" + | |
((char)(board.length+64)) + ") or a column (1-" + (board.length) + "). The free spaces in this sector become " + | |
"holes, while holed spaces become free spaces. Spaces containing items or avatars are not affected."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 13) { | |
deadLoop = cur; | |
msg(Colors.DARK_GREEN + bold(sender) + " discovers a dormant deadloop within the mainframe and executes it. As a result, " + | |
"other hackers will not receive information about their surroundings for one full round."); | |
} | |
else if(board[rr][cc] == 14) { | |
ArrayList<int[]> holes = new ArrayList<int[]>(); | |
for(int r = 0; r < board.length; r++) | |
for(int c = 0; c < board.length; c++) | |
if(board[r][c] == -1) | |
holes.add(new int[] {r,c}); | |
int n = (int)(Math.round(holes.size()/2.0)); | |
for(int i = 0; i < 7; i++) Collections.shuffle(holes); | |
for(int i = 0; i < n; i++) { | |
int[] loc = holes.remove(0); | |
board[loc[0]][loc[1]] = 0; | |
} | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes a defrag program. A random set of half of the holed " + | |
"grid spaces are reconfigured, becoming free spaces again."); | |
} | |
else if(board[rr][cc] == 15) { | |
itemUse = 15; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes the magic bullet program."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", publically declare \"column\" or \"row\". Any avatars in the same column or " + | |
"row (whichever was declared) as you are forced to hard reboot, removing them from the mainframe. Remember " + | |
"that your column is a number and your row is a letter."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 16) { | |
p.knight = true; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and installs White Knight (tm). You can now move to any location " + | |
"during your turn, instead of a location within the same row or column."); | |
} | |
else if(board[rr][cc] == 17) { | |
for(int r = 0; r < board.length; r++) | |
for(int c = 0; c < board.length; c++) | |
if(board[r][c] == 0) | |
board[r][c] = -1; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes a silhouette copy of the lengendary virus " + | |
"\"tangerine.exe\". Every space on the mainframe has been holed, except spaces containing avatars or items. " + | |
"A single cryptic message arrives in the program's readme text file: \"Never forget her. Never forget her. The " + | |
"Tangerine."); | |
} | |
else if(board[rr][cc] == 18) { | |
itemUse = 18; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes the magic bullet ][ program."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", first name a hacker. " + bold("Names are case-sensitive.")); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 19) { | |
p.cord = true; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and installs The Silver Cord. " + bold(sender) + " is now immune " + | |
"to slipping through a hole. After slipping through a hole once, The Silver Cord will break."); | |
} | |
else if(board[rr][cc] == 20) { | |
itemUse = 20; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes the Trojan virus, Masquerade Edition. "); | |
msg(Colors.DARK_GREEN + bold(sender) + ", PM me the name of a space that is in your same row or column. This space " + | |
"will be holed. If an avatar or program is on that space, they will be dropped from the mainframe."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 21) { | |
itemUse = 21; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes the Trojan virus, triple-M edition. "); | |
msg(Colors.DARK_GREEN + bold(sender) + ", PM me the name of a space. This space will be holed. If an avatar or program " + | |
"is on that space, they will be dropped from the mainframe."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 22) { | |
itemUse = 22; | |
multiTrojan = board.length; | |
msg(Colors.DARK_GREEN + bold(sender) + " finds a minesweeper."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", enter " + board.length + " spaces, one by one. If that space is a hole, " + | |
"it will be turned into a free space."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 23) { | |
itemUse = 23; | |
msg(Colors.DARK_GREEN + bold(sender) + " gains access to the parent directory, allowing for the execution of a " + | |
"\"dir.\" command."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", publically input the name of a row (A-" + | |
((char)(board.length+64)) + ") or a column (1-" + (board.length) + "). You will privately receive exact locations" + | |
" of any holes in that row or column."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if (board[rr][cc] == 24) { | |
itemUse = 24; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes Torchbearer (tm) by JourneymanWorks, who provide the " + | |
"latest in deckrunning technology at affordable prices!"); | |
msg(Colors.DARK_GREEN + bold(sender) + ", publically declare \"column\" or \"row\". The Torchbearer will retrieve " + | |
"information about every column or every row (whichever was selected) as if you were viewing those sectors. " + | |
"This information will arrive privately."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 25) { | |
itemUse = 25; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and executes \"Strangelove\", the third magic bullet virus."); | |
msg(Colors.DARK_GREEN + bold(sender) + ", enter the name of a space. If any avatar is on the same column or row, they " + | |
"will be ejected from the mainframe, and you will backdoor onto that space. However, if there are no avatars " + | |
"on that column or row, you will be reported to SysOps and will be ejected from the mainframe."); | |
board[p.r][p.c] = 1; | |
return; | |
} | |
else if(board[rr][cc] == 26) { | |
p.carpet = true; | |
msg(Colors.DARK_GREEN + bold(sender) + " downloads and installs The Flying Carpet. " + bold(sender) + " is now immune " + | |
"to slipping through a hole for the rest of the game. However, if he is rescued from a hole, the mainframe " + | |
"will publically say what square he is in."); | |
} | |
board[p.r][p.c] = 1; | |
cur++; | |
cur = cur % players.size(); | |
giveInfo(); | |
} | |
private String giveInfoR(int rr, int cc, int sc) { | |
String pl = "", i = ""; | |
int h = 0; | |
for(int c = 0; c < board.length; c++) { | |
if(sc == 0 && c == cc) continue; | |
if(board[rr][c] == -1) h++; | |
else if(board[rr][c] == 1) { | |
Player pp = findPlayer(rr,c); | |
if(!pp.cloak) pl += pp.name + ", "; | |
} | |
else if(board[rr][c] > 1) i += itemNames[board[rr][c]] + ", "; | |
} | |
StringBuffer s = new StringBuffer(); | |
if(pl.length() > 0) | |
s.append(pl.substring(0, pl.length() - 2)); | |
if(i.length() > 0) { | |
if(pl.length() > 0) s.append(", "); | |
s.append(i.substring(0, i.length() - 2)); | |
} | |
if(h > 0) { | |
if(pl.length() > 0 || i.length() > 0) s.append(" and "); | |
s.append("" + h + (h == 1? " hole": " holes")); | |
} | |
if(!pl.equals("") || h > 0 || !i.equals("")) s.append(" in row " + ((char)(rr+65)) + ". "); | |
return s.toString(); | |
} | |
private String giveInfoC(int rr, int cc, int sc) { | |
String pl = "", i = ""; | |
int h = 0; | |
for(int r = 0; r < board.length; r++) { | |
if(sc == 0 && r == rr) continue; | |
if(board[r][cc] == -1) h++; | |
else if(board[r][cc] == 1) { | |
Player pp = findPlayer(r, cc); | |
if(!pp.cloak) pl += pp.name + ", "; | |
} | |
else if(board[r][cc] > 1) i += itemNames[board[r][cc]] + ", "; | |
} | |
StringBuffer s = new StringBuffer(); | |
if(pl.length() > 0) | |
s.append(pl.substring(0, pl.length() - 2)); | |
if(i.length() > 0) { | |
if(pl.length() > 0) s.append(", "); | |
s.append(i.substring(0, i.length() - 2)); | |
} | |
if(h > 0) { | |
if(pl.length() > 0 || i.length() > 0) s.append(" and "); | |
s.append("" + h + (h == 1? " hole": " holes")); | |
} | |
if(!pl.equals("") || h > 0 || !i.equals("")) s.append(" in column " + (cc+1) + ". "); | |
return s.toString(); | |
} | |
private String giveInfo2(int rr, int cc, int sc) { | |
return giveInfoR(rr, cc, sc) + giveInfoC(rr, cc, sc); | |
} | |
private void notify30() { | |
turnTimer.cancel(); | |
msg(Colors.BLUE + bold(players.get(cur).name) + ", you have 30 seconds to make your move. You will be ejected from the " + | |
"mainframe if you do not make one."); | |
turnTimer = new Timer("Final timer"); | |
turnTimer.schedule(new TimerTask() { | |
public void run() { | |
noMoveTaken(); | |
} | |
}, 30000); | |
} | |
private void noMoveTaken() { | |
turnTimer.cancel(); | |
Player p = players.get(cur); | |
msg(Colors.RED + "The mainframe was unable to receive a PING acknowledgement from " + bold(p.name) + ". As a result, " + | |
bold(p.name) + " has been gracefully unjacked from the mainframe. His space will not be holed."); | |
board[p.r][p.c] = 0; | |
deVoice(chan, p.name); | |
players.remove(cur); | |
if(players.size() == 1) { | |
win(players.get(0).name); | |
return; | |
} | |
cur = cur % players.size(); | |
giveInfo(); | |
} | |
private void giveInfo() { | |
if(cur == 0) { | |
msg(Colors.BLUE + Colors.BOLD + "Round " + (++round) + "."); | |
if(roundsUntilSpawn == 0 && spawnInterval != -1) { | |
if(spawnInterval > 3) spawnInterval--; | |
roundsUntilSpawn = spawnInterval; | |
int r, c; | |
Random rnd = new Random(); | |
int rndNum = rnd.nextInt(itemProbsLen); | |
int n, sum; | |
for(n = 2, sum = 0; n < itemProbs.length; n++) { | |
sum += itemProbs[n]; | |
if(rndNum < sum || n == itemProbs.length - 1) break; | |
} | |
r = rnd.nextInt(board.length); | |
c = rnd.nextInt(board.length); | |
while(board[r][c] == 1) { | |
r = rnd.nextInt(board.length); | |
c = rnd.nextInt(board.length); | |
} | |
board[r][c] = n; | |
msg(Colors.DARK_GREEN + "Program loaded: " + itemNames[n] + "."); | |
} | |
else roundsUntilSpawn--; | |
} | |
msg(Colors.BLUE + bold(players.get(cur).name) + "\'s turn."); | |
giveInfo3(); | |
} | |
private void giveInfo3() { | |
turnTimer = new Timer("Initial timer"); | |
turnTimer.schedule(new TimerTask() { | |
public void run() { | |
notify30(); | |
} | |
}, 60000); | |
Player p = players.get(cur); | |
String s = "You are at " + p.loc() + ". "; | |
if(deadLoop == cur) deadLoop = -1; | |
if(deadLoop == -1) s += giveInfo2(p.r, p.c, 0); | |
else s += "You are adrift in a maelstrom of useless code. "; | |
s += "Where to?"; | |
sendMessage(p.name, s); | |
} | |
private Player findPlayer(int r, int c) { | |
for(Player p : players) { | |
if(p.r == r && p.c == c) | |
return p; | |
} | |
return null; | |
} | |
public class Player { | |
int r; | |
int c; | |
String name; | |
boolean cloak; | |
boolean ice; | |
boolean knight; | |
boolean cord; | |
boolean carpet; | |
//ArrayList<String> cookie = new ArrayList<String>(); | |
public Player(String n) { | |
name = n; | |
} | |
public String loc() { | |
return "" + ((char)(r+65)) + (c+1); | |
} | |
public String toString() { | |
return name; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment