|
|
@@ -6,7 +6,8 @@ import requests |
|
|
|
import datetime |
|
|
|
from html import unescape |
|
|
|
from random import shuffle |
|
|
|
from discord.ext.commands import group |
|
|
|
from collections import OrderedDict |
|
|
|
from discord.ext import commands |
|
|
|
|
|
|
|
|
|
|
|
""" |
|
|
@@ -64,7 +65,7 @@ class Trivia: |
|
|
|
else: |
|
|
|
# Get possible answers and shuffle them in a list |
|
|
|
incorrect = question["incorrect_answers"] |
|
|
|
correct = question["correct_answer"] |
|
|
|
correct = unescape(question["correct_answer"]) |
|
|
|
choices = [incorrect[0], incorrect[1], incorrect[2], correct] |
|
|
|
for answer in choices: |
|
|
|
choices[choices.index(answer)] = unescape(answer) |
|
|
@@ -72,9 +73,24 @@ class Trivia: |
|
|
|
# Then get the index of the correct answer |
|
|
|
correct = choices.index(correct) |
|
|
|
# Create output |
|
|
|
answers = "{} {}\n{} {}\n{} {}\n{} {}".format(str(self.emojis[0]), choices[0], str(self.emojis[1]), choices[1], str(self.emojis[2]), choices[2], str(self.emojis[3]), choices[3]) |
|
|
|
answers = "" |
|
|
|
for x in range(len(choices)): |
|
|
|
answers += "{} {}\n".format(str(self.emojis[x]), choices[x]) |
|
|
|
return output, answers, correct |
|
|
|
|
|
|
|
def calculate_scores(self, channel, message): |
|
|
|
score_added = {} |
|
|
|
for user, time in self.games[channel.id]["correct_users"].items(): |
|
|
|
seconds = (time - message.edited_at).total_seconds() |
|
|
|
seconds = round(seconds, 1) |
|
|
|
if seconds < 10: |
|
|
|
score = (10 - seconds) * 100 |
|
|
|
score = int(round(score, -2)) |
|
|
|
else: |
|
|
|
score = 50 |
|
|
|
score_added[user] = score # This is just to display the amount of score added to a user |
|
|
|
return score_added |
|
|
|
|
|
|
|
async def add_question_reactions(self, message, question): |
|
|
|
if question["type"] == "boolean": |
|
|
|
amount = 2 |
|
|
@@ -85,42 +101,71 @@ class Trivia: |
|
|
|
|
|
|
|
async def game(self, ctx, channel, questions): |
|
|
|
# For loop all the questions for the game, Maybe I should move the game dictionary here instead. |
|
|
|
# TODO: Defo needs some cleaning up |
|
|
|
for question in questions: |
|
|
|
# Parse question dictionary into something usable |
|
|
|
output, answers, correct = self.parse_question(question) |
|
|
|
self.games[channel.id]["correct_answer"] = correct |
|
|
|
|
|
|
|
# Send a message, add the emoji reactions, then edit in the question to avoid issues with answering before reactions are done. |
|
|
|
message = await ctx.send(output) |
|
|
|
await self.add_question_reactions(message, question) |
|
|
|
await message.edit(content=output+answers) |
|
|
|
|
|
|
|
# Set up variables for checking the question and if it's being answered |
|
|
|
players_yet_to_answer = list(self.games[channel.id]["players"].keys()) |
|
|
|
self.games[channel.id]["current_question"] = message |
|
|
|
# Wait for answers |
|
|
|
await asyncio.sleep(10) |
|
|
|
for x in range(20): |
|
|
|
for answered in self.games[channel.id]["players_answered"]: |
|
|
|
if answered in players_yet_to_answer: |
|
|
|
players_yet_to_answer.remove(answered) |
|
|
|
if not players_yet_to_answer: |
|
|
|
break |
|
|
|
else: |
|
|
|
await asyncio.sleep(1) |
|
|
|
|
|
|
|
# Code for checking if there are still players in the game goes here to make sure nothing breaks. |
|
|
|
if not self.games[channel.id]["players"]: |
|
|
|
await message.clear_reactions() |
|
|
|
await ctx.send("No more players to play the game") |
|
|
|
break |
|
|
|
|
|
|
|
# Clean up when answers have been submitted |
|
|
|
self.games[channel.id]["current_question"] = None |
|
|
|
await message.clear_reactions() |
|
|
|
|
|
|
|
# Display Correct answer and calculate and display scores. |
|
|
|
index = self.games[channel.id]["correct_answer"] |
|
|
|
await ctx.send("Correct Answer is {} '{}'".format(self.emojis[index], question["correct_answer"])) |
|
|
|
correct_out = "" |
|
|
|
for user, time in self.games[channel.id]["correct_users"].items(): |
|
|
|
seconds = (time - message.edited_at).total_seconds() |
|
|
|
correct_out += "{} answered correctly in {}s\n".format(discord.utils.get(ctx.guild.members, id=user), seconds) |
|
|
|
if not correct_out: |
|
|
|
await ctx.send("No one got anything right.") |
|
|
|
else: |
|
|
|
await ctx.send(correct_out) |
|
|
|
await ctx.send("Correct Answer is {} '{}'".format(self.emojis[index], unescape(question["correct_answer"]))) |
|
|
|
|
|
|
|
# Scores |
|
|
|
scores_to_add = self.calculate_scores(channel, message) |
|
|
|
for user in scores_to_add: |
|
|
|
self.games[channel.id]["players"][user] += scores_to_add[user] |
|
|
|
|
|
|
|
# Display scores |
|
|
|
updated_scores = dict(self.games[channel.id]["players"]) |
|
|
|
for player in updated_scores: |
|
|
|
if player in self.games[channel.id]["correct_users"]: |
|
|
|
updated_scores[player] = str(updated_scores[player]) + " (+{})".format(scores_to_add[player]) |
|
|
|
else: |
|
|
|
updated_scores[player] = str(updated_scores[player]) |
|
|
|
updated_scores = OrderedDict(sorted(updated_scores.items(), key=lambda kv: kv)) |
|
|
|
output_scores = "" |
|
|
|
for scores in updated_scores: |
|
|
|
output_scores += "{}: {}\n".format(scores, updated_scores[scores]) |
|
|
|
|
|
|
|
await ctx.send(output_scores) |
|
|
|
|
|
|
|
# Display that |
|
|
|
# Final checks for next question |
|
|
|
self.games[channel.id]["correct_users"] = {} |
|
|
|
self.games[channel.id]["players_answered"] = [] |
|
|
|
# make sure to check that there is still players playing after a question |
|
|
|
|
|
|
|
|
|
|
|
# Game Naturally Ends |
|
|
|
# Game Ends |
|
|
|
# Some stuff here displaying score |
|
|
|
|
|
|
|
self.games.pop(channel.id) |
|
|
|
await ctx.send("GAME END") |
|
|
|
|
|
|
@@ -128,9 +173,8 @@ class Trivia: |
|
|
|
|
|
|
|
async def on_reaction_add(self, reaction, user): |
|
|
|
"""Logic for answering a question""" |
|
|
|
# TODO: Debug this. |
|
|
|
time = datetime.datetime.now() |
|
|
|
if user == self.bot.user: # reaction.me isnt working idk why |
|
|
|
if user == self.bot.user: |
|
|
|
return |
|
|
|
|
|
|
|
channel = reaction.message.channel |
|
|
@@ -152,11 +196,12 @@ class Trivia: |
|
|
|
|
|
|
|
# Commands |
|
|
|
|
|
|
|
@group(aliases=["tr"]) |
|
|
|
@commands.group(aliases=["tr"]) |
|
|
|
async def trivia(self, ctx): |
|
|
|
pass |
|
|
|
|
|
|
|
@trivia.command() |
|
|
|
@commands.bot_has_permissions(manage_messages=True) |
|
|
|
async def start(self, ctx, amount = "medium"): |
|
|
|
channel = ctx.channel |
|
|
|
player = ctx.author |