Make trivia have a functional scoreboard
This commit is contained in:
parent
48fdb32e15
commit
96f298b654
@ -0,0 +1,31 @@
|
|||||||
|
package wtf.beatrice.hidekobot.objects;
|
||||||
|
|
||||||
|
import net.dv8tion.jda.api.entities.User;
|
||||||
|
|
||||||
|
public class TriviaScore
|
||||||
|
{
|
||||||
|
|
||||||
|
private final User user;
|
||||||
|
private int score = 0;
|
||||||
|
|
||||||
|
public TriviaScore(User user)
|
||||||
|
{
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeScore(int add)
|
||||||
|
{
|
||||||
|
score += add;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getScore() { return score; }
|
||||||
|
|
||||||
|
public User getUser() { return user; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString()
|
||||||
|
{
|
||||||
|
return "[" + user.getAsTag() + "," + score + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package wtf.beatrice.hidekobot.objects.comparators;
|
||||||
|
|
||||||
|
import wtf.beatrice.hidekobot.objects.TriviaScore;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class gets two trivia scores, and compares their score.
|
||||||
|
*/
|
||||||
|
public class TriviaScoreComparator implements Comparator<TriviaScore> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(TriviaScore o1, TriviaScore o2) {
|
||||||
|
return Integer.compare(o2.getScore(), o1.getScore()); // inverted, because higher number should come first
|
||||||
|
}
|
||||||
|
}
|
@ -9,13 +9,12 @@ import net.dv8tion.jda.api.interactions.components.buttons.Button;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import wtf.beatrice.hidekobot.Cache;
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
import wtf.beatrice.hidekobot.objects.TriviaQuestion;
|
import wtf.beatrice.hidekobot.objects.TriviaQuestion;
|
||||||
|
import wtf.beatrice.hidekobot.objects.TriviaScore;
|
||||||
|
import wtf.beatrice.hidekobot.objects.comparators.TriviaScoreComparator;
|
||||||
import wtf.beatrice.hidekobot.util.CommandUtil;
|
import wtf.beatrice.hidekobot.util.CommandUtil;
|
||||||
import wtf.beatrice.hidekobot.util.TriviaUtil;
|
import wtf.beatrice.hidekobot.util.TriviaUtil;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.concurrent.ScheduledFuture;
|
import java.util.concurrent.ScheduledFuture;
|
||||||
|
|
||||||
public class TriviaTask implements Runnable
|
public class TriviaTask implements Runnable
|
||||||
@ -47,12 +46,13 @@ public class TriviaTask implements Runnable
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run()
|
||||||
|
{
|
||||||
if(previousMessage != null)
|
if(previousMessage != null)
|
||||||
{
|
{
|
||||||
// todo: we shouldn't use this method, since it messes with the database...
|
// todo: we shouldn't use this method, since it messes with the database...
|
||||||
CommandUtil.disableExpired(previousMessage.getId());
|
CommandUtil.disableExpired(previousMessage.getId());
|
||||||
|
|
||||||
String previousCorrectAnswer = questions.get(iteration-1).correctAnswer();
|
String previousCorrectAnswer = questions.get(iteration-1).correctAnswer();
|
||||||
|
|
||||||
// we need this to be thread-locking to avoid getting out of sync with the rest of the trivia features
|
// we need this to be thread-locking to avoid getting out of sync with the rest of the trivia features
|
||||||
@ -65,11 +65,73 @@ public class TriviaTask implements Runnable
|
|||||||
|
|
||||||
if(iteration >= questions.size())
|
if(iteration >= questions.size())
|
||||||
{
|
{
|
||||||
// todo: nicer-looking embed with stats
|
|
||||||
// we need this to be thread-locking to avoid getting out of sync with the rest of the trivia features
|
|
||||||
channel.sendMessage("Trivia session is over!").complete();
|
|
||||||
|
|
||||||
|
String scoreboardText = "\uD83D\uDC23 Trivia session is over!";
|
||||||
|
|
||||||
|
List<String> winners = new ArrayList<>();
|
||||||
|
int topScore = 0;
|
||||||
|
StringBuilder othersBuilder = new StringBuilder();
|
||||||
|
|
||||||
|
LinkedList<TriviaScore> triviaScores = new LinkedList<>(TriviaUtil.channelAndScores.get(channel.getId()));
|
||||||
|
triviaScores.sort(new TriviaScoreComparator());
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
Integer previousScore = null;
|
||||||
|
for(TriviaScore triviaScore : triviaScores)
|
||||||
|
{
|
||||||
|
if(pos > 10) break; // cap at top 10
|
||||||
|
|
||||||
|
String user = triviaScore.getUser().getAsMention();
|
||||||
|
int score = triviaScore.getScore();
|
||||||
|
if(previousScore == null)
|
||||||
|
{
|
||||||
|
previousScore = score;
|
||||||
|
topScore = score;
|
||||||
|
pos = 1;
|
||||||
|
} else {
|
||||||
|
if(score != previousScore) pos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pos == 1) winners.add(user);
|
||||||
|
else {
|
||||||
|
othersBuilder.append("\n").append(pos)
|
||||||
|
.append(" | ").append(user)
|
||||||
|
.append(": ").append(score).append(" points");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder winnersBuilder = new StringBuilder();
|
||||||
|
for(int i = 0; i < winners.size(); i++)
|
||||||
|
{
|
||||||
|
String winner = winners.get(i);
|
||||||
|
winnersBuilder.append(winner);
|
||||||
|
if(i + 1 != winners.size())
|
||||||
|
{
|
||||||
|
winnersBuilder.append(", "); // separate with comma except on last run
|
||||||
|
} else {
|
||||||
|
winnersBuilder.append(": ").append(topScore).append(" points \uD83C\uDF89");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String winnersTitle = "\uD83D\uDCAB ";
|
||||||
|
winnersTitle += winners.size() == 1 ? "Winner" : "Winners";
|
||||||
|
|
||||||
|
|
||||||
|
EmbedBuilder scoreboardBuilder = new EmbedBuilder();
|
||||||
|
scoreboardBuilder.setColor(Cache.getBotColor());
|
||||||
|
scoreboardBuilder.setTitle("\uD83C\uDF1F Trivia Scoreboard");
|
||||||
|
scoreboardBuilder.addField(winnersTitle, winnersBuilder.toString(), false);
|
||||||
|
scoreboardBuilder.addField("☁️ Others", othersBuilder.toString(), false);
|
||||||
|
|
||||||
|
channel.sendMessage(scoreboardText).addEmbeds(scoreboardBuilder.build()).queue();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// remove all cached data
|
||||||
TriviaUtil.channelsRunningTrivia.remove(channel.getId());
|
TriviaUtil.channelsRunningTrivia.remove(channel.getId());
|
||||||
|
TriviaUtil.channelAndWhoResponded.remove(channel.getId());
|
||||||
|
TriviaUtil.channelAndScores.remove(channel.getId());
|
||||||
|
|
||||||
future.cancel(false);
|
future.cancel(false);
|
||||||
// we didn't implement null checks on the future on purpose, because we need to know if we were unable
|
// we didn't implement null checks on the future on purpose, because we need to know if we were unable
|
||||||
// to cancel it (and console errors should make it clear enough).
|
// to cancel it (and console errors should make it clear enough).
|
||||||
@ -110,9 +172,9 @@ public class TriviaTask implements Runnable
|
|||||||
EmbedBuilder embedBuilder = new EmbedBuilder();
|
EmbedBuilder embedBuilder = new EmbedBuilder();
|
||||||
|
|
||||||
embedBuilder.setColor(Cache.getBotColor());
|
embedBuilder.setColor(Cache.getBotColor());
|
||||||
embedBuilder.setTitle("Trivia (" + (iteration+1) + "/" + questions.size() + ")");
|
embedBuilder.setTitle("\uD83C\uDFB2 Trivia (" + (iteration+1) + "/" + questions.size() + ")");
|
||||||
|
|
||||||
embedBuilder.addField("Question", currentTriviaQuestion.question(), false);
|
embedBuilder.addField("❓ Question", currentTriviaQuestion.question(), false);
|
||||||
|
|
||||||
previousMessage = channel
|
previousMessage = channel
|
||||||
.sendMessageEmbeds(embedBuilder.build())
|
.sendMessageEmbeds(embedBuilder.build())
|
||||||
|
@ -8,6 +8,7 @@ import org.json.JSONArray;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
import wtf.beatrice.hidekobot.Cache;
|
import wtf.beatrice.hidekobot.Cache;
|
||||||
import wtf.beatrice.hidekobot.objects.TriviaQuestion;
|
import wtf.beatrice.hidekobot.objects.TriviaQuestion;
|
||||||
|
import wtf.beatrice.hidekobot.objects.TriviaScore;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -28,6 +29,9 @@ public class TriviaUtil
|
|||||||
// first string is the channelId, the list contain all users who responded there
|
// first string is the channelId, the list contain all users who responded there
|
||||||
public static HashMap<String, List<String>> channelAndWhoResponded = new HashMap<>();
|
public static HashMap<String, List<String>> channelAndWhoResponded = new HashMap<>();
|
||||||
|
|
||||||
|
// first string is the channelId, the list contain all score records for that channel
|
||||||
|
public static HashMap<String, List<TriviaScore>> channelAndScores = new HashMap<>();
|
||||||
|
|
||||||
public static JSONObject fetchTrivia()
|
public static JSONObject fetchTrivia()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
@ -80,19 +84,47 @@ public class TriviaUtil
|
|||||||
|
|
||||||
public static void handleAnswer(ButtonInteractionEvent event, AnswerType answerType)
|
public static void handleAnswer(ButtonInteractionEvent event, AnswerType answerType)
|
||||||
{
|
{
|
||||||
if(trackResponse(event.getUser(), event.getChannel()))
|
User user = event.getUser();
|
||||||
|
String channelId = event.getChannel().getId();
|
||||||
|
|
||||||
|
if(trackResponse(user, event.getChannel()))
|
||||||
{
|
{
|
||||||
|
List<TriviaScore> scores = channelAndScores.get(channelId);
|
||||||
|
if(scores == null) scores = new ArrayList<>();
|
||||||
|
TriviaScore currentUserScore = null;
|
||||||
|
for(TriviaScore score : scores)
|
||||||
|
{
|
||||||
|
if(score.getUser().equals(user))
|
||||||
|
{
|
||||||
|
currentUserScore = score;
|
||||||
|
scores.remove(score);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(currentUserScore == null)
|
||||||
|
{
|
||||||
|
currentUserScore = new TriviaScore(user);
|
||||||
|
}
|
||||||
|
|
||||||
if(answerType.equals(AnswerType.CORRECT))
|
if(answerType.equals(AnswerType.CORRECT))
|
||||||
{
|
{
|
||||||
event.reply(event.getUser().getAsMention() + " got it right!").queue();
|
|
||||||
|
event.reply(user.getAsMention() + " got it right! \uD83E\uDD73 (**+3**)").queue();
|
||||||
|
currentUserScore.changeScore(3);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
event.reply(event.getUser().getAsMention() + ", that's not the right answer!").queue();
|
event.reply("❌ " + user.getAsMention() + ", that's not the right answer! (**-1**)").queue();
|
||||||
|
currentUserScore.changeScore(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scores.add(currentUserScore);
|
||||||
|
channelAndScores.put(channelId, scores);
|
||||||
} else {
|
} else {
|
||||||
event.reply(event.getUser().getAsMention() + ", you can't answer twice!")
|
event.reply("☹️ " + user.getAsMention() + ", you can't answer twice!")
|
||||||
.queue(message ->
|
.queue(interaction ->
|
||||||
Cache.getTaskScheduler().schedule(() ->
|
Cache.getTaskScheduler().schedule(() ->
|
||||||
message.deleteOriginal().queue(), 5, TimeUnit.SECONDS));
|
interaction.deleteOriginal().queue(), 3, TimeUnit.SECONDS));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user