Skip to content

Instantly share code, notes, and snippets.

@Vazkii
Created August 21, 2014 00:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Vazkii/e7d91c96fe60178a3de3 to your computer and use it in GitHub Desktop.
Save Vazkii/e7d91c96fe60178a3de3 to your computer and use it in GitHub Desktop.
Bot Game Show
package vazkii.vbot.gameshow;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Queue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.jibble.pircbot.Colors;
import org.jibble.pircbot.User;
import vazkii.vbot.VBot;
public final class GameShow extends Thread {
private static final String START_REGEX = "^\\?start (#\\w+) (.+)$";
public static VBot bot; // Replace with your bot. Must extend PircBot
private static GameShow runningShow;
boolean invalid = false;
String channel;
String name;
String starter;
int currQuestion;
String victor = "";
Queue<Question> questions;
Map<String, Integer> playerScores;
public GameShow(String sender, String channel, String url) {
this(sender, channel, propsFromURL(sender, url));
}
public GameShow(String sender, String channel, Properties props) {
if(props == null) {
invalid = true;
return;
}
this.channel = channel;
name = props.getProperty("name").trim();
starter = sender;
int questions = Integer.parseInt(props.getProperty("questions").trim());
String doublepoint = props.getProperty("doublepoint").trim();
List<String> doublepointList = Arrays.asList(doublepoint.split(";"));
this.questions = new LinkedList<Question>();
for(int i = 1; i < questions + 1; i++) {
String q, a;
try {
q = props.getProperty("question" + i).trim();
a = props.getProperty("answer" + i).trim();
} catch(NullPointerException e) {
bot.sendMessage(sender, "Either question" + i + " or answer" + i + " are missing. Please review your file.");
throw(e);
}
List<String> alist = Arrays.asList(a.split(";"));
boolean doubleq = doublepointList.contains("" + i);
Question question = new Question(q, alist, doubleq);
this.questions.add(question);
}
playerScores = new HashMap<String, Integer>();
currQuestion = 1;
setDaemon(true);
}
public static Properties propsFromURL(String sender, String url) {
Properties props = new Properties();
try {
props.load(new URL(url).openStream());
} catch(Exception e) {
bot.sendMessage(sender, e.getMessage());
return null;
}
return props;
}
// Called onMessage from your bot
public static void onMessageStatic(String channel, String sender, String login, String hostname, String message) {
if(runningShow != null)
runningShow.onMessage(channel, sender, login, hostname, message);
}
// Called onPrivateMessage from your bot
// op = is the person who sent this PM an OP?
public static void onPrivateMessageStatic(String sender, String login, String hostname, String message, boolean op) {
if(runningShow != null)
runningShow.onPrivateMessage(sender, login, hostname, message, op);
else if(message.equals("?mgs"))
mgs(sender);
else {
Pattern pattern = Pattern.compile(START_REGEX);
Matcher matcher = pattern.matcher(message.trim());
if(matcher.matches()) {
String channel = matcher.group(1);
if(channel.equals(VBot.gameshowChannel) || op) {
String url = matcher.group(2);
GameShow show = new GameShow(sender, channel, url);
if(!show.invalid) {
runningShow = show;
try {
runningShow.start();
bot.sendMessage(sender, "You have started your game! If you wish to stop it, write ?disband");
} catch(Exception e) {}
}
} else bot.sendMessage(sender, "You are not an admin, you can't create games on channels other than #modgameshow.");
}
}
}
public static void mgs(String sender) {
bot.sendMessage(sender, "Welcome to the Mod Game Show. Making your own trivia game is simple. Just follow the template here:");
bot.sendMessage(sender, "http://vazkii.us/gameshow.txt");
}
@Override
public void run() {
try {
bot.sendMessage(channel, starter + " is starting the " + name + "! The game will start in 60 seconds, get ready!!");
for(int i = 0; i < 5; i++) {
sleep(10000);
bot.sendMessage(channel, ((5 - i) * 10) + " seconds left!");
}
sleep(6000);
bot.sendMessage(channel, "The " + name + " (started by " + starter + ") is about to start!!");
for(int i = 0; i < 3; i++) {
sleep(1000);
bot.sendMessage(channel, (3 - i) + "!!");
}
sleep(1000);
bot.sendMessage(channel, "START!!");
while(!questions.isEmpty()) {
Question question = questions.peek();
String questionStr = question.q;
boolean antiping = false;
for(User user : bot.getUsers(channel)) {
if(questionStr.contains(user.getNick())) {
questionStr = questionStr.replaceAll(user.getNick().replaceAll("(\\w+)(\\w)", "($1)($2)"), "$1" + "." + "$2");
antiping = true;
}
}
if(antiping)
questionStr = questionStr + Colors.YELLOW + " (. added to prevent pinging)";
bot.sendMessage(channel, Colors.TEAL + "QUESTION #" + currQuestion + "!" + Colors.GREEN + " " + questionStr + (question.bonus ? (Colors.RED + " (Bonus Point!)") : ""));
sleep(15000);
String end = Colors.GREEN + (questions.size() == 1 ? " This was the last question!" : " Next question in 5 seconds!");
if(!victor.isEmpty()) {
bot.sendMessage(channel, Colors.TEAL + victor + " got the question right!" + end);
int score = question.bonus ? 2 : 1;
if(!playerScores.containsKey(victor))
playerScores.put(victor, score);
else playerScores.put(victor, playerScores.get(victor) + score);
victor = "";
} else
bot.sendMessage(channel, Colors.RED + "Seems like nobody got the question right... :(" + end);
questions.poll();
++currQuestion;
if(!questions.isEmpty())
sleep(5000);
}
String scores = "";
List<String> scoreList = new ArrayList<String>();
for(String player : playerScores.keySet())
scoreList.add(playerScores.get(player) + ":" + player);
Collections.sort(scoreList, new Comparator<String>() {
@Override public int compare(String arg0, String arg1) {
int a = Integer.parseInt(arg0.split(":")[0]);
int b = Integer.parseInt(arg1.split(":")[0]);
return b - a;
}});
for(String s : scoreList) {
String[] tokens = s.split(":");
scores = scores + tokens[1] + " - " + tokens[0] + " | ";
}
bot.sendMessage(channel, Colors.CYAN + "And this is the end of the " + name + "! Here are the scores!");
bot.sendMessage(channel, Colors.MAGENTA + scores.trim().replaceAll(" \\|$", ""));
} catch (InterruptedException e) {
runningShow = null;
}
runningShow = null;
}
public void onMessage(String channel, String sender, String login, String hostname, String message) {
if(victor.isEmpty()) {
String answer = message.trim();
for(String a : questions.peek().a)
if(answer.replaceAll("[^a-zA-Z0-9 -]", "").equalsIgnoreCase(a)) {
victor = sender;
break;
}
}
}
public void onPrivateMessage(String sender, String login, String hostname, String message, boolean op) {
if(message.trim().equals("?disband")) {
if(op || sender.equals(starter)) {
bot.sendMessage(channel, "The game has been disbanded by " + (op ? "an admin" : "the game host") + ".");
runningShow = null;
interrupt();
} else bot.sendMessage(sender, "You are not the host of the current game, you can't do that.");
} else if(message.equals("?mgs"))
mgs(sender);
else bot.sendMessage(sender, "There's already a game running, please wait until it ends.");
}
}
package vazkii.vbot.gameshow;
import java.util.List;
public class Question {
public final String q;
public final List<String> a;
public final boolean bonus;
public Question(String q, List<String> a, boolean bonus) {
this.q = q;
this.a = a;
this.bonus = bonus;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment