aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bot/exts/events/trivianight/_questions.py72
-rw-r--r--bot/exts/events/trivianight/_scoreboard.py17
-rw-r--r--bot/exts/events/trivianight/trivianight.py31
3 files changed, 101 insertions, 19 deletions
diff --git a/bot/exts/events/trivianight/_questions.py b/bot/exts/events/trivianight/_questions.py
index f558c50e..df3f237a 100644
--- a/bot/exts/events/trivianight/_questions.py
+++ b/bot/exts/events/trivianight/_questions.py
@@ -1,6 +1,6 @@
from random import choice, randrange
from time import perf_counter
-from typing import Union
+from typing import TypedDict, Union
import discord
from discord import Embed, Interaction
@@ -10,6 +10,15 @@ from bot.constants import Colours, NEGATIVE_REPLIES
from ._scoreboard import Scoreboard
+class CurrentQuestion(TypedDict):
+ """Representing the different 'keys' of the question taken from the JSON."""
+
+ number: str
+ description: str
+ answers: list
+ correct: str
+
+
class QuestionButton(Button):
"""Button subclass for the options of the questions."""
@@ -25,10 +34,26 @@ class QuestionButton(Button):
"""When a user interacts with the button, this will be called."""
if interaction.user.id not in self.users_picked.keys():
self.users_picked[interaction.user.id] = [self.label, 1, perf_counter() - self._time]
+ await interaction.response.send_message(
+ embed=Embed(
+ title="Success!",
+ description=f"You chose answer choice {self.label}.",
+ color=Colours.soft_green
+ ),
+ ephemeral=True
+ )
elif self.users_picked[interaction.user.id][1] < 2:
self.users_picked[interaction.user.id] = [
self.label, self.users_picked[interaction.user.id][1] + 1, perf_counter() - self._time
]
+ await interaction.response.send_message(
+ embed=Embed(
+ title="Success!",
+ description=f"You changed your answer to answer choice {self.label}.",
+ color=Colours.soft_green
+ ),
+ ephemeral=True
+ )
else:
await interaction.response.send_message(
embed=Embed(
@@ -45,7 +70,7 @@ class QuestionView(View):
def __init__(self):
super().__init__()
- self.current_question = {}
+ self.current_question: CurrentQuestion
self.users_picked = {}
self.buttons = [QuestionButton(label, self.users_picked) for label in ("A", "B", "C", "D")]
for button in self.buttons:
@@ -91,26 +116,51 @@ class Questions:
def __init__(self, scoreboard: Scoreboard):
self.scoreboard = scoreboard
self.questions = []
- self._ptr = -1
def set_questions(self, questions: list) -> None:
"""Setting `self.questions` dynamically via a function to set it."""
self.questions = questions
- def next_question(self) -> Union[Embed, None]:
- """Uses another, new question."""
- if all("visited" in question.keys() for question in self.questions.values()):
+ def next_question(self, number: int = None) -> Union[Embed, None]:
+ """
+ Chooses a random unvisited question from the question bank.
+
+ If the number parameter is specified, it'll head to that specific question.
+ """
+ if all("visited" in question.keys() for question in self.questions):
return Embed(
title=choice(NEGATIVE_REPLIES),
description="All of the questions in the question bank have been used.",
color=Colours.soft_red
)
- while "visited" in self.questions[self._ptr].keys():
- self._ptr = randrange(0, len(self.questions))
+ if number is None:
+ question_number = randrange(0, len(self.questions))
+ while "visited" in self.questions[question_number].keys():
+ question_number = randrange(0, len(self.questions))
+ else:
+ question_number = number
+
+ self.questions[question_number]["visited"] = True
+ self.view.current_question = self.questions[question_number]
+
+ def list_questions(self) -> str:
+ """
+ Lists all questions from the question bank.
+
+ It will put the following into a message:
+ - Question number
+ - Question description
+ - If the question was already 'visited' (displayed)
+ """
+ spaces = len(sorted(self.questions, key=lambda question: len(question['description']))[-1]["description"]) + 3
+ formatted_string = ""
+ for question in self.questions:
+ formatted_string += f"`Q{question['number']}: {question['description']!r}" \
+ f"{' ' * (spaces - len(question['description']) + 2)}" \
+ f"|` {':x:' if not question.get('visited') else ':checkmark:'}\n"
- self.questions[self._ptr]["visited"] = True
- self.view.current_question = self.questions[self._ptr]
+ return formatted_string.strip()
def current_question(self) -> tuple[Embed, QuestionView]:
"""Returns an embed entailing the current question as an embed with a view."""
@@ -120,7 +170,7 @@ class Questions:
"""Terminates answering of the question and displays the correct answer."""
scores, answer_embed = self.view.end_question()
for user, score in scores.items():
- self.scoreboard[f"points: {user}"] = score[1]
+ self.scoreboard[f"points: {user}"] = 1
self.scoreboard[f"speed: {user}"] = score[2]
return answer_embed
diff --git a/bot/exts/events/trivianight/_scoreboard.py b/bot/exts/events/trivianight/_scoreboard.py
index cab0288f..7eb7a6a8 100644
--- a/bot/exts/events/trivianight/_scoreboard.py
+++ b/bot/exts/events/trivianight/_scoreboard.py
@@ -25,14 +25,14 @@ class ScoreboardView(View):
color=Colours.python_blue,
)
- # Limit self.points.items() to 10 items at maximum (top 10 users) in the future
- for user, points in list(self.points.items()):
+ current_placement = 1
+ for user, points in self.points.items():
user = await self.bot.fetch_user(int(user))
main_embed.add_field(
- name=f"{user.name}#{user.discriminator}",
- value=f"`{points}` pts",
- inline=False
+ name=f"{current_placement}. {user.name}#{user.discriminator}",
+ value=f"`{points}` pts"
)
+ current_placement += 1
return main_embed
@@ -43,13 +43,14 @@ class ScoreboardView(View):
description="See the leaderboard for how fast each user took to answer a question correctly!",
color=Colours.python_blue,
)
- for user, time_taken in list(self.speed.items()):
+ current_placement = 1
+ for user, time_taken in self.speed.items():
user = await self.bot.fetch_user(int(user))
speed_embed.add_field(
- name=f"{user.name}#{user.discriminator}",
+ name=f"{current_placement}. {user.name}#{user.discriminator}",
value=f"`{(time_taken[1] / time_taken[0]):.3f}s` (on average)",
- inline=False
)
+ current_placement += 1
return speed_embed
diff --git a/bot/exts/events/trivianight/trivianight.py b/bot/exts/events/trivianight/trivianight.py
index 609f6651..2ec869ab 100644
--- a/bot/exts/events/trivianight/trivianight.py
+++ b/bot/exts/events/trivianight/trivianight.py
@@ -41,6 +41,20 @@ class TriviaNight(commands.Cog):
await ctx.send(embed=success_embed)
@trivianight.command()
+ async def reset(self, ctx: commands.Context) -> None:
+ """Resets previous questions and scoreboards."""
+ self.scoreboard.view = ScoreboardView(self.bot)
+ for question in self.questions.questions:
+ del question["visited"]
+
+ success_embed = Embed(
+ title=choice(POSITIVE_REPLIES),
+ description="The scoreboards were reset and questions marked unvisited!",
+ color=Colours.soft_green
+ )
+ await ctx.send(embed=success_embed)
+
+ @trivianight.command()
async def next(self, ctx: commands.Context) -> None:
"""Gets a random question from the unanswered question list and lets user choose the answer."""
next_question = self.questions.next_question()
@@ -52,6 +66,23 @@ class TriviaNight(commands.Cog):
await ctx.send(embed=question_embed, view=question_view)
@trivianight.command()
+ async def question(self, ctx: commands.Context, question_number: int) -> None:
+ """Gets a question from the question bank depending on the question number provided."""
+ question = self.questions.next_question(question_number)
+ if isinstance(question, Embed):
+ await ctx.send(embed=question)
+ return
+
+ question_embed, question_view = self.questions.current_question()
+ await ctx.send(embed=question_embed, view=question_view)
+
+ @trivianight.command()
+ async def list(self, ctx: commands.Context) -> None:
+ """Displays all the questions from the question bank."""
+ formatted_string = self.questions.list_questions()
+ await ctx.send(formatted_string)
+
+ @trivianight.command()
async def stop(self, ctx: commands.Context) -> None:
"""End the ongoing question to show the correct question."""
await ctx.send(embed=self.questions.end_question())