Trivia

This commit is contained in:
NikolajDanger
2021-04-18 14:42:21 +02:00
committed by Nikolaj
parent 883f84f569
commit fd9bde73c6
2 changed files with 150 additions and 61 deletions

View File

@ -1,94 +1,175 @@
import json """
import urllib Contains code for trivia games.
import random
import asyncio *Classes*
---------
Trivia
Contains all the code for the trivia commands.
"""
import urllib # Used to get data from api
import json # Used to read data from api
import random # Used to shuffle answers
import asyncio # Used to sleep
from discord_slash.context import SlashContext # Used for type hints
class Trivia(): class Trivia():
"""
Contains the code for trivia games.
*Methods*
---------
triviaStart(channel: str) -> str, str, str
triviaAnswer(user: str, channel: str, command: str) -> str
triviaCountPoints(channel: str)
triviaParse(ctx: SlashContext, answer: str)
"""
def __init__(self, bot): def __init__(self, bot):
"""Initialize the class."""
self.bot = bot self.bot = bot
# Starts a game of trivia. Downloads a question with answers, shuffles the wrong answers with the def triviaStart(self, channel: str):
# correct answer and returns the questions and answers. Also saves the question in the games.json file. """
def triviaStart(self, channel : str): Start a game of trivia.
question = self.bot.database["trivia questions"].find_one({"_id":channel})
self.bot.log("Trying to find a trivia question for "+channel) Downloads a question with answers, shuffles the wrong answers
with the correct answer and returns the questions and answers.
Also saves the question in the database.
if question == None: *Parameters*
with urllib.request.urlopen("https://opentdb.com/api.php?amount=10&type=multiple") as response: ------------
channel: str
The id of the channel to start the game in
*Returns*
---------
sendMessage: str
The message to return to the user.
"""
triviaQuestions = self.bot.database["trivia questions"]
question = triviaQuestions.find_one({"_id": channel})
self.bot.log(f"Trying to find a trivia question for {channel}")
if question is None:
apiUrl = "https://opentdb.com/api.php?amount=10&type=multiple"
with urllib.request.urlopen(apiUrl) as response:
data = json.loads(response.read()) data = json.loads(response.read())
self.bot.log("Found the question \""+data["results"][0]["question"]+"\"") question = data["results"][0]["question"]
self.bot.log(f"Found the question \"{question}\"")
answers = data["results"][0]["incorrect_answers"] answers = data["results"][0]["incorrect_answers"]
answers.append(data["results"][0]["correct_answer"]) answers.append(data["results"][0]["correct_answer"])
random.shuffle(answers) random.shuffle(answers)
correctAnswer = answers.index(data["results"][0]["correct_answer"]) + 97 correctAnswer = data["results"][0]["correct_answer"]
correctAnswer = answers.index(correctAnswer) + 97
self.bot.database["trivia questions"].insert_one({"_id":channel,"answer" : str(chr(correctAnswer)),"players" : {}}) newQuestion = {
"_id": channel,
"answer": str(chr(correctAnswer)),
"players": {}
}
triviaQuestions.insert_one(newQuestion)
replacements = {"'": "\'", replacements = {
""": "\"", "'": "\'",
"“": "\"", """: "\"",
"”": "\"", "“": "\"",
"é": "é"} "”": "\"",
"é": "é"
}
question = data["results"][0]["question"] question = data["results"][0]["question"]
for key, value in replacements.items(): for key, value in replacements.items():
question = question.replace(key,value) question = question.replace(key, value)
for answer in answers: for answer in answers:
for key, value in replacements.items(): for key, value in replacements.items():
answer = answer.replace(key,value) answer = answer.replace(key, value)
return question, answers, correctAnswer return question, answers, correctAnswer
else: else:
self.bot.log("There was already a trivia question for that channel (error code 1106)") logMessage = "There was already a trivia question for that channel"
return "There's already a trivia question going on. Try again in like, a minute (error code 1106)", "", "" self.bot.log(logMessage)
return self.bot.longStrings["Trivia going on"], "", ""
# Lets players answer a trivia question def triviaAnswer(self, user: str, channel: str, command: str):
def triviaAnswer(self, user : str, channel : str, command : str): """
question = self.bot.database["trivia questions"].find_one({"_id":channel}) Answer the current trivia question.
if command in ["a","b","c","d"]: *Parameters*
if question != None: ------------
if user not in question["players"]: user: str
self.bot.log(user+" answered the question in "+channel) The id of the user who answered.
channel: str
The id of the channel the game is in.
command: str
The user's answer.
self.bot.database["trivia questions"].update_one({"_id":channel},{"$set":{"players."+user : command}}) *Returns*
---------
sendMessage: str
The message to send if the function failed.
"""
triviaQuestions = self.bot.database["trivia questions"]
question = triviaQuestions.find_one({"_id": channel})
return "Locked in "+user+"'s answer" if command not in ["a", "b", "c", "d"]:
else: self.bot.log("I didn't quite understand that")
self.bot.log(user+" has already answered this question (error code 1105)") return "I didn't quite understand that"
return user+" has already answered this question (error code 1105)" elif question is None:
else: self.bot.log("There's no question right now")
self.bot.log("There's no question right now (error code 1104)") return "There's no question right now"
return "There's no question right now (error code 1104)" elif user in question["players"]:
self.bot.log(f"{user} has already answered this question")
return f"{user} has already answered this question"
else: else:
self.bot.log("I didn't quite understand that (error code 1103)") self.bot.log(f"{user} answered the question in {channel}")
return "I didn't quite understand that (error code 1103)"
updater = {"$set": {f"players.{user}": command}}
triviaQuestions.update_one({"_id": channel}, updater)
return None
# Adds 1 GwendoBuck to each player that got the question right and deletes question from games.json. def triviaCountPoints(self, channel: str):
def triviaCountPoints(self, channel : str): """
question = self.bot.database["trivia questions"].find_one({"_id":channel}) Add money to every winner's account.
*Parameters*
------------
channel: str
The id of the channel the game is in.
"""
triviaQuestions = self.bot.database["trivia questions"]
question = triviaQuestions.find_one({"_id": channel})
self.bot.log("Counting points for question in "+channel) self.bot.log("Counting points for question in "+channel)
if question != None: if question is not None:
for player, answer in question["players"].items(): for player, answer in question["players"].items():
if answer == question["answer"]: if answer == question["answer"]:
self.bot.money.addMoney(player,1) self.bot.money.addMoney(player, 1)
else: else:
self.bot.log("Couldn't find the question (error code 1102)") self.bot.log("Couldn't find the questio")
return None return None
async def triviaParse(self, ctx, answer): async def triviaParse(self, ctx: SlashContext, answer: str):
"""
Parse a trivia command.
*Parameters*
------------
ctx: SlashContext
The context of the command.
answer: str
The answer, if any.
"""
await self.bot.defer(ctx) await self.bot.defer(ctx)
channelId = str(ctx.channel_id)
if answer == "": if answer == "":
question, options, correctAnswer = self.triviaStart(str(ctx.channel_id)) question, options, correctAnswer = self.triviaStart(channelId)
if options != "": if options != "":
results = "**"+question+"**\n" results = "**"+question+"**\n"
for x, option in enumerate(options): for x, option in enumerate(options):
@ -98,21 +179,27 @@ class Trivia():
await asyncio.sleep(60) await asyncio.sleep(60)
self.triviaCountPoints(str(ctx.channel_id)) self.triviaCountPoints(channelId)
self.bot.databaseFuncs.deleteGame("trivia questions",str(ctx.channel_id)) deleteGameParams = ["trivia questions", channelId]
self.bot.databaseFuncs.deleteGame(*deleteGameParams)
self.bot.log("Time's up for the trivia question",str(ctx.channel_id)) self.bot.log("Time's up for the trivia question", channelId)
await ctx.send("Time's up The answer was \"*"+chr(correctAnswer)+") "+options[correctAnswer-97]+"*\". Anyone who answered that has gotten 1 GwendoBuck") sendMessage = self.bot.longStrings["Trivia time up"]
formatParams = [chr(correctAnswer), options[correctAnswer-97]]
sendMessage = sendMessage.format(*formatParams)
await ctx.send(sendMessage)
else: else:
await ctx.send(question, hidden=True) await ctx.send(question, hidden=True)
elif answer in ["a","b","c","d"]: elif answer in ["a", "b", "c", "d"]:
response = self.triviaAnswer("#"+str(ctx.author.id), str(ctx.channel_id), answer) userId = f"#{ctx.author.id}"
if response.startswith("Locked in "): response = self.triviaAnswer(userId, channelId, answer)
await ctx.send(f"{ctx.author.display_name} answered **{answer}**") if response is None:
userName = ctx.author.display_name
await ctx.send(f"{userName} answered **{answer}**")
else: else:
await ctx.send(response) await ctx.send(response)
else: else:
self.bot.log("I didn't understand that (error code 1101)",str(ctx.channel_id)) self.bot.log("I didn't understand that", channelId)
await ctx.send("I didn't understand that (error code 1101)") await ctx.send("I didn't understand that")

View File

@ -10,5 +10,7 @@
"Blackjack started": "Blackjack game started. Use \"/blackjack bet [amount]\" to enter the game within the next 30 seconds.", "Blackjack started": "Blackjack game started. Use \"/blackjack bet [amount]\" to enter the game within the next 30 seconds.",
"Blackjack going on": "There's already a blackjack game going on. Try again in a few minutes.", "Blackjack going on": "There's already a blackjack game going on. Try again in a few minutes.",
"Stock value": "The current {} stock is valued at **{}** GwendoBucks", "Stock value": "The current {} stock is valued at **{}** GwendoBucks",
"Stock parameters": "You must give both a stock name and an amount of GwendoBucks you wish to spend." "Stock parameters": "You must give both a stock name and an amount of GwendoBucks you wish to spend.",
"Trivia going on": "There's already a trivia question going on. Try again in like, a minute",
"Trivia time up": "Time's up! The answer was \"*{}) {}*\". Anyone who answered that has gotten 1 GwendoBuck"
} }