aboutsummaryrefslogtreecommitdiffstats
path: root/bot/seasons/evergreen/trivia_quiz.py
diff options
context:
space:
mode:
authorGravatar RohanJnr <[email protected]>2019-10-02 09:38:20 +0530
committerGravatar RohanJnr <[email protected]>2019-10-02 09:38:20 +0530
commitabce0ecc6a072d6d25035c6b55d45f2f85327c22 (patch)
treefa86272f673ccc0d84489bbae0d5045d0991ae4b /bot/seasons/evergreen/trivia_quiz.py
parentadded function annotations to the check method (diff)
Worked on the requested changes and also made a few other changes:
- when the user uses the command to stop the game, the bot fails to reply back with the winners list. This is because the varibale player_data is being initialised to {} at the start of the command. I solved this by making a player_data variable in the cog __init__() with the channel id being the key and dict as value
Diffstat (limited to 'bot/seasons/evergreen/trivia_quiz.py')
-rw-r--r--bot/seasons/evergreen/trivia_quiz.py139
1 files changed, 68 insertions, 71 deletions
diff --git a/bot/seasons/evergreen/trivia_quiz.py b/bot/seasons/evergreen/trivia_quiz.py
index ac72ed95..c7778c88 100644
--- a/bot/seasons/evergreen/trivia_quiz.py
+++ b/bot/seasons/evergreen/trivia_quiz.py
@@ -30,9 +30,10 @@ class TriviaQuiz(commands.Cog):
self.questions = self.load_questions()
self.game_status = {}
self.game_owners = {}
- self.question_limit = 3
+ self.question_limit = 4
+ self.player_dict = {}
self.categories = {
- "general": "Test your general knwoledge"
+ "general": "Test your general knowledge"
# "retro": "Questions related to retro gaming."
}
@@ -44,8 +45,8 @@ class TriviaQuiz(commands.Cog):
questions = json.load(json_data)
return questions
- @commands.command(name="quiz")
- async def quiz_game(self, ctx: commands.Context, option: str, category: str = "general") -> None:
+ @commands.command(name="quiz", aliases=["trivia", "tquiz"])
+ async def quiz_game(self, ctx: commands.Context, category: str = "general") -> None:
"""
Start/Stop a quiz!
@@ -59,42 +60,36 @@ class TriviaQuiz(commands.Cog):
(we wil be adding more later)
"""
category = category.lower()
- player_data = {} # a dict to store players and their points.
+ # player_data = {} # a dict to store players and their points.
if ctx.channel.id not in self.game_status:
- self.game_status[ctx.channel.id] = None
-
- if option == "start":
- if self.game_status[ctx.channel.id] is True:
- await ctx.send("Game already running.")
- return
- else:
- self.game_owners[ctx.channel.id] = ctx.author
- self.game_status[ctx.channel.id] = True
- start_embed = discord.Embed(colour=discord.Colour.red())
- start_embed.title = "Quiz game Starting!!"
- start_embed.description = "Each game consists of 5 questions.\n"
- start_embed.description += "**Rules :**\nNo cheating and have fun!"
- start_embed.set_footer(
- text="Points for that question reduces by 25 after 10s.Total time is 30s per question"
- )
- await ctx.send(embed=start_embed) # send an embed with the rules
- await asyncio.sleep(1)
-
- elif option == "stop":
- if self.game_status[ctx.channel.id] is False:
- await ctx.send("No game running, nothing to stop here.")
- return
+ self.game_status[ctx.channel.id] = False
+ self.player_dict[ctx.channel.id] = {}
+
+ if not self.game_status[ctx.channel.id]:
+ self.game_owners[ctx.channel.id] = ctx.author
+ self.game_status[ctx.channel.id] = True
+ start_embed = discord.Embed(colour=discord.Colour.red())
+ start_embed.title = "Quiz game Starting!!"
+ start_embed.description = "Each game consists of 5 questions.\n"
+ start_embed.description += "**Rules :**\nNo cheating and have fun!"
+ start_embed.set_footer(
+ text="Points for a question reduces by 25 after 10s or after a hint.Total time is 30s per question"
+ )
+ await ctx.send(embed=start_embed) # send an embed with the rules
+ await asyncio.sleep(1)
+
+ else:
+ if (
+ ctx.author == self.game_owners[ctx.channel.id]
+ or Roles.moderator in [role.id for role in ctx.author.roles]
+ ):
+ await ctx.send("Quiz is no longer running.")
+ await self.declare_winner(ctx.channel, self.player_dict[ctx.channel.id])
+ self.game_status[ctx.channel.id] = False
+ del self.game_owners[ctx.channel.id]
else:
- if (
- ctx.author == self.game_owners[ctx.channel.id]
- or Roles.moderator in [role.id for role in ctx.author.roles]
- ):
- await self.declare_winner(ctx.channel, player_data)
- self.game_status[ctx.channel.id] = False
- del self.game_owners[ctx.channel.id]
- else:
- await ctx.send(f"{ctx.author.mention}, you are not authorised to stop this game :ghost: !")
+ await ctx.send(f"{ctx.author.mention}, you are not authorised to stop this game :ghost: !")
if category not in self.categories:
embed = self.category_embed
@@ -106,15 +101,14 @@ class TriviaQuiz(commands.Cog):
done_question = []
hint_no = 0
answer = None
- hints = None
- while self.game_status[ctx.channel.id] is True:
+ while self.game_status[ctx.channel.id]:
if len(done_question) > self.question_limit and hint_no == 0:
await ctx.send("The round ends here.")
- await self.declare_winner(ctx.channel, player_data)
+ await self.declare_winner(ctx.channel, self.player_dict[ctx.channel.id])
break
if unanswered > 3:
await ctx.send("Game stopped due to inactivity.")
- await self.declare_winner(ctx.channel, player_data)
+ await self.declare_winner(ctx.channel, self.player_dict[ctx.channel.id])
break
if hint_no == 0:
while True:
@@ -132,42 +126,43 @@ class TriviaQuiz(commands.Cog):
def check(m: discord.Message) -> bool:
ratio = fuzz.ratio(answer.lower(), m.content.lower())
- return ratio > 80 and m.channel == ctx.channel
+ return ratio > 85 and m.channel == ctx.channel
try:
msg = await self.bot.wait_for('message', check=check, timeout=10)
- except Exception as e:
+ except asyncio.TimeoutError:
if self.game_status[ctx.channel.id] is False:
break
- if isinstance(e, asyncio.TimeoutError):
- if hint_no < 2:
- hint_no += 1
- if "hints" in question_dict:
- hints = question_dict["hints"]
- await ctx.send(f"**Hint #{hint_no+1}\n**{hints[hint_no]}")
- else:
- await ctx.send(f"Cmon guys, {30-hint_no*10}s left!")
-
+ if hint_no < 2:
+ hint_no += 1
+ if "hints" in question_dict:
+ hints = question_dict["hints"]
+ await ctx.send(f"**Hint #{hint_no+1}\n**{hints[hint_no]}")
else:
- response = random.choice(WRONG_ANS_RESPONSE)
- expression = random.choice(ANNOYED_EXPRESSIONS)
- await ctx.send(f"{response} {expression}")
- await self.send_answer(ctx.channel, question_dict)
- await asyncio.sleep(1)
- hint_no = 0
- unanswered += 1
- await self.send_score(ctx.channel, player_data)
+ await ctx.send(f"Cmon guys, {30-hint_no*10}s left!")
+
+ else:
+ response = random.choice(WRONG_ANS_RESPONSE)
+ expression = random.choice(ANNOYED_EXPRESSIONS)
+ await ctx.send(f"{response} {expression}")
+ await self.send_answer(ctx.channel, question_dict)
+ await asyncio.sleep(1)
+ hint_no = 0
+ unanswered += 1
+ await self.send_score(ctx.channel, self.player_dict[ctx.channel.id])
+ await asyncio.sleep(2)
else:
points = 100 - 25*hint_no
- if msg.author in player_data:
- player_data[msg.author] += points
+ if msg.author in self.player_dict[ctx.channel.id]:
+ self.player_dict[ctx.channel.id][msg.author] += points
else:
- player_data[msg.author] = points
+ self.player_dict[ctx.channel.id][msg.author] = points
hint_no = 0
unanswered = 0
await ctx.send(f"{msg.author.mention} got the correct answer :tada: {points} points for ya.")
await self.send_answer(ctx.channel, question_dict)
- await self.send_score(ctx.channel, player_data)
+ await self.send_score(ctx.channel, self.player_dict[ctx.channel.id])
+ await asyncio.sleep(2)
@staticmethod
async def send_score(channel: discord.TextChannel, player_data: dict) -> None:
@@ -181,13 +176,14 @@ class TriviaQuiz(commands.Cog):
@staticmethod
async def declare_winner(channel: discord.TextChannel, player_data: dict) -> None:
- """A function declare the winner of the quiz."""
+ """Announce the winner of the quiz in the game channel."""
if player_data:
highest_points = max(list(player_data.values()))
no_of_winners = list(player_data.values()).count(highest_points)
# Check if more than 1 player has highest points.
if no_of_winners > 1:
+ word = "You guys"
winners = []
points_copy = list(player_data.values()).copy()
for _ in range(no_of_winners):
@@ -199,17 +195,18 @@ class TriviaQuiz(commands.Cog):
winners_mention += f"{winner.mention} "
else:
+ word = "You"
author_index = list(player_data.values()).index(highest_points)
winner = list(player_data.keys())[author_index]
winners_mention = winner.mention
await channel.send(
f"Congratz {winners_mention} :tada: "
- f"You have won this quiz game with a grand total of {highest_points} points!!"
+ f"{word} have won this quiz game with a grand total of {highest_points} points!!"
)
@property
def category_embed(self) -> discord.Embed:
- """A function which returns an embed showing all avilable categories."""
+ """Build an embed showing all available trivia categories."""
embed = discord.Embed(colour=discord.Colour.blue())
embed.title = "The available question categories are:"
embed.description = ""
@@ -220,19 +217,19 @@ class TriviaQuiz(commands.Cog):
@staticmethod
async def send_answer(channel: discord.TextChannel, question_dict: dict) -> None:
- """A function that sends the answer."""
+ """Send the correct the answer of a question to the game channel."""
answer = question_dict["answer"]
info = question_dict["info"]
embed = discord.Embed(color=discord.Colour.red())
embed.title = f"The correct answer is **{answer}**\n"
embed.description = ""
if info != "":
- embed.description += f"**Information**\n{info}\n"
- embed.description += "Lets move to the next question."
+ embed.description += f"**Information**\n{info}\n\n"
+ embed.description += "Lets move to the next question.\nRemaining questions: "
await channel.send(embed=embed)
def setup(bot: commands.Bot) -> None:
"""Loading the cog."""
bot.add_cog(TriviaQuiz(bot))
- logger.debug("TriviaQuiz cog loaded!")
+ logger.debug("TriviaQuiz cog loaded")