From 5a305fd588e0e07b308ad5ca68a19d25d7e1fe22 Mon Sep 17 00:00:00 2001 From: RohanJnr Date: Mon, 23 Sep 2019 19:07:08 +0530 Subject: corrected my spelling mistake on the file name --- bot/seasons/evergreen/travia_quiz.py | 225 ----------------------------------- bot/seasons/evergreen/trivia_quiz.py | 225 +++++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 225 deletions(-) delete mode 100644 bot/seasons/evergreen/travia_quiz.py create mode 100644 bot/seasons/evergreen/trivia_quiz.py diff --git a/bot/seasons/evergreen/travia_quiz.py b/bot/seasons/evergreen/travia_quiz.py deleted file mode 100644 index 84a16654..00000000 --- a/bot/seasons/evergreen/travia_quiz.py +++ /dev/null @@ -1,225 +0,0 @@ -import asyncio -import json -import logging -import random -from pathlib import Path - -import discord -from discord.ext import commands -from fuzzywuzzy import fuzz - -from bot.constants import Roles - - -logger = logging.getLogger(__name__) - - -annoyed_expressions = ["-_-", "-.-"] - -wrong_ans_responses = [ - "No one gave the correct answer", - "Losers", - "You guys really need to learn" -] - -game_rules = [ - "No cheating!", - "Idk what rules to put in here haha." - -] - - -class TriviaQuiz(commands.Cog): - """A cog for all quiz commands.""" - - def __init__(self, bot): - self.bot = bot - self.questions = self.load_questions() - self.game_status = {} - self.game_owners = {} - self.question_limit = 3 - self.categories = { - "general": "Test your general knwoledge", - "retro": "Questions related to retro gaming." - } - - @staticmethod - def load_questions() -> dict: - """Load the questions from json file.""" - p = Path("bot", "resources", "evergreen", "trivia_quiz.json") - with p.open() as json_data: - questions = json.load(json_data) - return questions - - @commands.command(name="quiz") - async def start(self, ctx, option: str, category: str = "retro") -> None: - """ - Start/Stop a quiz! - - arguments: - option: - - start : to start a quiz in a channel - - stop : stop the quiz running in that channel. - - Questions for the quiz can be selected from the following categories: - - general : Test your general knowledge. (default) - - Retro : questions related to retro gaming. - """ - category = category.lower() - 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: - return await ctx.send("Game already running.") - 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 :**\n" - for rule in game_rules: - start_embed.description += f"- {rule}\n" - start_embed.set_footer(text="2 hints per question sent after every 10s") - await ctx.send(embed=start_embed) # send an embed with the rules - - elif option == "stop": - if self.game_status[ctx.channel.id] is False: - return await ctx.send("No game running, nothing to stop here.") - 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 - else: - await ctx.send(f"{ctx.author.mention}, you are not authorised to stop this game :ghost: !") - else: - self.game_status[ctx.channel.id] = False - return await ctx.send("start or stop only") - - unanswerd = 0 - done_question = [] - hint_no = 0 - answer = None - hints = None - while self.game_status[ctx.channel.id] is True: - 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) - break - if unanswerd > 3: - await ctx.send("Game stopped due to inactivity.") - await self.declare_winner(ctx.channel, player_data) - break - if category not in self.categories: - embed = self.category_embed - await ctx.send(embed=embed) - break - topic = self.questions[category] - if hint_no == 0: - while True: - question_dict = random.choice(topic) - if question_dict["id"] not in done_question: - done_question.append(question_dict["id"]) - break - q = question_dict["question"] - answer = question_dict["answer"] - hints = question_dict["hints"] - - embed = discord.Embed(colour=discord.Colour.gold()) - embed.title = f"Question #{len(done_question)}" - embed.description = q - await ctx.send(embed=embed) - - def check(m): - ratio = fuzz.ratio(answer.lower(), m.content) - return ratio > 80 and m.channel == ctx.channel - try: - msg = await self.bot.wait_for('message', check=check, timeout=10) - except Exception as e: - if self.game_status[ctx.channel.id] is False: - break - if isinstance(e, asyncio.TimeoutError): - if hint_no < 2: - await ctx.send(f"**Hint #{hint_no+1}\n**{hints[hint_no]}") - hint_no += 1 - else: - response = random.choice(wrong_ans_responses) - expression = random.choice(annoyed_expressions) - await ctx.send(f"{response} {expression}, the correct answer is **{answer}**.") - hint_no = 0 - unanswerd += 1 - await self.send_score(ctx.channel, player_data) - - else: - points = 100 - 25*hint_no - if msg.author in player_data: - player_data[msg.author] += points - else: - player_data[msg.author] = points - hint_no = 0 - unanswerd = 0 - await ctx.send(f"{msg.author.mention} got the correct answer :tada: {points} points for ya.") - await ctx.send(f"Correct answer is **{answer}**") - await self.send_score(ctx.channel, player_data) - - @staticmethod - async def send_score(channel, player_data): - """A function which sends the score.""" - embed = discord.Embed(colour=discord.Colour.blue()) - embed.title = "Score Board" - embed.description = "" - for k, v in player_data.items(): - embed.description += f"{k} : {v}\n" - await channel.send(embed=embed) - - @staticmethod - async def declare_winner(channel, player_data): - """A function declare the winner of the quiz.""" - - 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: - winners = [] - points_copy = list(player_data.values()).copy() - for _ in range(no_of_winners): - index = points_copy.index(highest_points) - winners.append(list(player_data.keys())[index]) - points_copy[index] = 0 - winners_mention = None - for winner in winners: - winners_mention += f"{winner.mention} " - - else: - 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!!" - ) - - @property - def category_embed(self) -> discord.Embed: - """A function which returns an embed showing all avilable categories.""" - embed = discord.Embed(colour=discord.Colour.blue()) - embed.title = "The available question categories are:" - embed.description = "" - for cat, description in self.categories.items(): - embed.description += f"**- {cat.capitalize()}**\n{description.capitalize()}\n" - embed.set_footer(text="If not category is chosen, then a random one will be selected.") - return embed - - -def setup(bot): - """Loading the cog.""" - bot.add_cog(TriviaQuiz(bot)) - logger.debug("TriviaQuiz cog loaded!") diff --git a/bot/seasons/evergreen/trivia_quiz.py b/bot/seasons/evergreen/trivia_quiz.py new file mode 100644 index 00000000..84a16654 --- /dev/null +++ b/bot/seasons/evergreen/trivia_quiz.py @@ -0,0 +1,225 @@ +import asyncio +import json +import logging +import random +from pathlib import Path + +import discord +from discord.ext import commands +from fuzzywuzzy import fuzz + +from bot.constants import Roles + + +logger = logging.getLogger(__name__) + + +annoyed_expressions = ["-_-", "-.-"] + +wrong_ans_responses = [ + "No one gave the correct answer", + "Losers", + "You guys really need to learn" +] + +game_rules = [ + "No cheating!", + "Idk what rules to put in here haha." + +] + + +class TriviaQuiz(commands.Cog): + """A cog for all quiz commands.""" + + def __init__(self, bot): + self.bot = bot + self.questions = self.load_questions() + self.game_status = {} + self.game_owners = {} + self.question_limit = 3 + self.categories = { + "general": "Test your general knwoledge", + "retro": "Questions related to retro gaming." + } + + @staticmethod + def load_questions() -> dict: + """Load the questions from json file.""" + p = Path("bot", "resources", "evergreen", "trivia_quiz.json") + with p.open() as json_data: + questions = json.load(json_data) + return questions + + @commands.command(name="quiz") + async def start(self, ctx, option: str, category: str = "retro") -> None: + """ + Start/Stop a quiz! + + arguments: + option: + - start : to start a quiz in a channel + - stop : stop the quiz running in that channel. + + Questions for the quiz can be selected from the following categories: + - general : Test your general knowledge. (default) + - Retro : questions related to retro gaming. + """ + category = category.lower() + 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: + return await ctx.send("Game already running.") + 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 :**\n" + for rule in game_rules: + start_embed.description += f"- {rule}\n" + start_embed.set_footer(text="2 hints per question sent after every 10s") + await ctx.send(embed=start_embed) # send an embed with the rules + + elif option == "stop": + if self.game_status[ctx.channel.id] is False: + return await ctx.send("No game running, nothing to stop here.") + 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 + else: + await ctx.send(f"{ctx.author.mention}, you are not authorised to stop this game :ghost: !") + else: + self.game_status[ctx.channel.id] = False + return await ctx.send("start or stop only") + + unanswerd = 0 + done_question = [] + hint_no = 0 + answer = None + hints = None + while self.game_status[ctx.channel.id] is True: + 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) + break + if unanswerd > 3: + await ctx.send("Game stopped due to inactivity.") + await self.declare_winner(ctx.channel, player_data) + break + if category not in self.categories: + embed = self.category_embed + await ctx.send(embed=embed) + break + topic = self.questions[category] + if hint_no == 0: + while True: + question_dict = random.choice(topic) + if question_dict["id"] not in done_question: + done_question.append(question_dict["id"]) + break + q = question_dict["question"] + answer = question_dict["answer"] + hints = question_dict["hints"] + + embed = discord.Embed(colour=discord.Colour.gold()) + embed.title = f"Question #{len(done_question)}" + embed.description = q + await ctx.send(embed=embed) + + def check(m): + ratio = fuzz.ratio(answer.lower(), m.content) + return ratio > 80 and m.channel == ctx.channel + try: + msg = await self.bot.wait_for('message', check=check, timeout=10) + except Exception as e: + if self.game_status[ctx.channel.id] is False: + break + if isinstance(e, asyncio.TimeoutError): + if hint_no < 2: + await ctx.send(f"**Hint #{hint_no+1}\n**{hints[hint_no]}") + hint_no += 1 + else: + response = random.choice(wrong_ans_responses) + expression = random.choice(annoyed_expressions) + await ctx.send(f"{response} {expression}, the correct answer is **{answer}**.") + hint_no = 0 + unanswerd += 1 + await self.send_score(ctx.channel, player_data) + + else: + points = 100 - 25*hint_no + if msg.author in player_data: + player_data[msg.author] += points + else: + player_data[msg.author] = points + hint_no = 0 + unanswerd = 0 + await ctx.send(f"{msg.author.mention} got the correct answer :tada: {points} points for ya.") + await ctx.send(f"Correct answer is **{answer}**") + await self.send_score(ctx.channel, player_data) + + @staticmethod + async def send_score(channel, player_data): + """A function which sends the score.""" + embed = discord.Embed(colour=discord.Colour.blue()) + embed.title = "Score Board" + embed.description = "" + for k, v in player_data.items(): + embed.description += f"{k} : {v}\n" + await channel.send(embed=embed) + + @staticmethod + async def declare_winner(channel, player_data): + """A function declare the winner of the quiz.""" + + 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: + winners = [] + points_copy = list(player_data.values()).copy() + for _ in range(no_of_winners): + index = points_copy.index(highest_points) + winners.append(list(player_data.keys())[index]) + points_copy[index] = 0 + winners_mention = None + for winner in winners: + winners_mention += f"{winner.mention} " + + else: + 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!!" + ) + + @property + def category_embed(self) -> discord.Embed: + """A function which returns an embed showing all avilable categories.""" + embed = discord.Embed(colour=discord.Colour.blue()) + embed.title = "The available question categories are:" + embed.description = "" + for cat, description in self.categories.items(): + embed.description += f"**- {cat.capitalize()}**\n{description.capitalize()}\n" + embed.set_footer(text="If not category is chosen, then a random one will be selected.") + return embed + + +def setup(bot): + """Loading the cog.""" + bot.add_cog(TriviaQuiz(bot)) + logger.debug("TriviaQuiz cog loaded!") -- cgit v1.2.3