瀏覽代碼

More code optimisations, added score calculation and score addition. Now also displays scores. Also added a check for permissions so that the bot doesn't run into any errors when trying to remove reactions.

tags/v1.4.0
roxie 6 年之前
父節點
當前提交
be47805ed3
共有 1 個文件被更改,包括 64 次插入19 次删除
  1. +64
    -19
      cogs/trivia.py

+ 64
- 19
cogs/trivia.py 查看文件

@@ -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

Loading…
取消
儲存