Skip to content
Advertisement

Discord.py creating a reaction game

What I’ve tried

StackOverflow articles

Need help to fix a certain bug in rock, scissor and paper.

discord.py documentation

How can I add reaction to a message (checked plenty of articles, but I’m not going to add them in order to get into the point)

I’ve managed to retrieve the emoji from the user in the check method, but still the issue with timeouterror appears, so there is something I’m missing which I can’t get a hold on.

In this senario im using Cog,

The issue

Even though the wait_for passes the check method, I’m not sure how to send it forward to the logical conditon. The result I get is passed in the exception.

bot.py

import os
from dotenv import load_dotenv
from discord import Intents

# lib

from lib.cog.miniGames import miniGames                         #   Games 
from lib.client.krigjo25 import krigjo25

# Importing .evn file
load_dotenv()

def botSetup ():

     # necsessary values from .env
    botKey = os.getenv('Token')
    server = os.getenv('server')
    

            # discord configs
    intents= Intents.all()

        #retrieving the module command prefix is created in the bot module
    bot=krigjo25(intents=intents)

        # adding cogs into the bot
    bot.add_cog(miniGames(bot))
    bot.run(botKey)
    
if __name__ == '__main__':
    botSetup()

miniGames.py

class miniGames(Cog, name='miniGames module'):
    def __init__(self, bot):
        self.bot = bot

    @command(name='rsp')
    @Cog.listener()
    #   1:  Creating a game where the user has three choices to choose between from
    #   2:  The bot adds 3 reactions, where you have to choose one of them as an answer
    #   3:  The bot checks wheter the conditions is true or false, in order to send the correct messge:

    async def RockscissorsPaper(self, message:Message):

        # Declearing variables 
        
                        # Rock, Scissors, Paper
        rock,scissor, paper = 'U0001FAA8', 'U00002702','U0001F4C4'

        answer = {  0:'U0001FAA8',
                    1:'U00002702',
                    2:'U0001F4C4'}

        # Randomizing the answer and assign it to the variable            
        shuffle(answer)
        x = randrange(0,2)
        answer = 'U0001FAA8' #answer.get(x)

        print(answer)

        # Creating Embed message
        embed = Embed(color = Color.blurple())
        embed.title = 'Rock, Scissors & Paper'
        embed.description = ' In order to play the game, please click one one of the following reactions'
        
        # Sending & adding reactions
        ch = await message.channel.send(embed=embed)
        await ch.add_reaction(rock)
        await ch.add_reaction(scissor)
        await ch.add_reaction(paper) 

              # passes the check method
        def check( user, reaction):
            print('check function', reaction, user)
            return user == message.author and reaction == str(reaction.emoji)
         # Checks the user's input¨'
         # Questions : Is it possible to use dictionaries in order to find the given emoji?

        try :
            # How does this work? If wait_for is a "asynico" function how can it work like this?
            reaction, user = await self.bot.wait_for('reaction_add', timeout=30, check=check)
        except TimeoutError as e:
            print(e)
        
        else:
            reaction = str(reaction.emoji)
            # Checking if its the bots reaction
            if user == self.bot.user:
                return None
            else:
                if reaction == 'U0001F4C4' and answer == 'U0001FAA8':
                    await message.channel.send(' you won')

Advertisement

Answer

It appears that i had to change :

def check( user, reaction):
        print('check function', reaction, user)
        return user == message.author and reaction == str(reaction.emoji)

New

     def emojiCheck(reaction, member):
        reaction = str(reaction)
        member == ctx.author.name
        # Do not return the bot's last reaction
        return member !=self.bot.user and reaction

— I also had to add the code block in the try – except statement.

** OLD **

 try :
        # How does this work? If wait_for is a "asynico" function how can it work like this?
        reaction, user = await self.bot.wait_for('reaction_add', timeout=30, check=check)
    except TimeoutError as e:
        print(e)
    
    else:
        reaction = str(reaction.emoji)
        # Checking if its the bots reaction
        if user == self.bot.user:
            return None
        else:
            if reaction == 'U0001F4C4' and answer == 'U0001FAA8':
                await message.channel.send(' you won')

New

 try:
                                                        #           Timer               Check
        reaction, member = await self.bot.wait_for('reaction_add', timeout=60.0, check=emojiCheck)
        print(member, reaction, answer)
        
        # Dictionaries
            # Tie
        tie = { 
            0:f'{self.bot.user} draws a **tie** for {member}',
            1:'Sir, lets **tie** a **tie**',
            2:'What did the **tie** say to the bowtie? You're a weirdo',
            3:'lets have a wii-match',
        }
        reactionRock = {

        }
        # Randomize the dictionary
        shuffle(tie)
        x = randrange(0,3)
        tie = tie.get(x)

            # If the situation is a draw / tie
        if str(reaction) == answer:
                self.embed.description = tie
                await ctx.send(embed = self.embed)

The point is if-elif or else statement has to be inside the try-except statement.

Hope this is for help for other developers which has the same issue. Thanks for the assistance which I received. Its appreciated.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement