im making a guessing game and im trying to use the client.wait_for function for it but the problem is this function looks at all the messages being sent after you have run it but I want it to only look at one person's messages. I also tried this:
if guess.author != user: return
which did work, it would stop the code if someone else talked when you are using the bot but if someone speaks on another server when you are using the bot it will still be stopped.
if it could only read one person's messages it would be nice.
my full code:
user=message.author
number = random.randint(1, 100)
await message.channel.send('I have a number in mind between 1 and 100, you have 7 guesses, guess.')
for guesses in range(0, 7):
guess = await client.wait_for('message')
if guess.author !=user:
await message.channel.send("sorry game ended cus someone talked mid game.(this can happen if people talk even if not in this sever)")
return
if int(guess.content) < number:
if guesses == 6:
await message.channel.send("Too many guesses, try again.")
await message.channel.send("The number I was thinking of was " + str(number) + ".")
break
else:
await message.channel.send("Higher!")
elif int(guess.content) > number:
if guesses == 6:
await message.channel.send("Too many guesses, try again.")
await message.channel.send("The number I was thinking of was " + str(number) + ".")
break
else:
await message.channel.send("Lower!")
else:
await message.channel.send("You got it! You guessed " + str(guesses + 1) + " times.")
break
You can pass a check to your wait_for like this:
guess = await client.wait_for("message", check=lambda message: message.author.id == user_id)
Using a custom check allows you to actually use custom checks, you can use any method returning a bool, that way you can even use things unrelated to the bot itself, python is the limit.
def check(msg):
return msg.author == ctx.author and msg.channel == ctx.channel
msg = await self.client.wait_for("message", check=check)
Related
I made a number-guessing command in Discord.py. The command works perfectly fine outside of any cogs folder (main.py). Because my main.py was getting cluttered, I relocated the guess command into one of the cog's folders where I organized my other commands. When I ran the bot and try to use the guess command, I get an error saying:
loop attribute cannot be accessed in non-async contexts. Consider using either an asynchronous main function and passing it to asyncio.run or using asynchronous initialisation hooks such as Client.setup_hooktype
Below is the code I used for the guess command inside the cog:
#commands.command()
async def guess(self, ctx):
try:
await ctx.send(f"Pick a range of numbers you want and the number of attempts you want."
f"Ex: '__**1-10**, **4**__' or '__**600-10**, **200**__'")
def check(msg):
return msg.author == ctx.author and msg.channel == ctx.channel
msg = await client.wait_for('message', check=check)
user_range = msg.content
num = re.findall(r'\d+', user_range) # get the values from the msg.content or user input
range_1 = int(num[0])
range_2 = int(num[1])
attempt = int(num[2])
if range_1 > range_2:
range_1 = int(num[1])
range_2 = int(num[0])
await ctx.send(
f"Now guess a number between **{range_1}-{range_2}**, you have **{attempt}** attempts. Type 'stop' to give up.")
def check(msg):
return msg.author == ctx.author and msg.channel == ctx.channel
Entry = 0
ran_picker = random.randrange(range_1, range_2)
while Entry <= attempt:
msg = await client.await_for('message', check=check)
Entry = Entry + 1
if msg.content == "stop" or msg.content == "Stop":
await ctx.send(f"You gave up 😢")
await ctx.send(f"The number was **{ran_picker}**")
break
elif int(msg.content) == ran_picker:
await ctx.send(f"**Good job, it was {ran_picker}!**")
break
elif int(msg.content) > range_2 or int(msg.content) < range_1:
await ctx.send(f"Pick a number between **{range_1}-{range_2}**!")
Entry = Entry - 1
print(Entry)
elif Entry == attempt:
await ctx.send(f"You ran out of inputs, it was **{ran_picker}**!")
break
else:
await ctx.send(f"Nope, keep guessing", delete_after=2)
else:
await ctx.send(
f"Now guess a number between **{range_1}-{range_2}**, you have **{attempt}** attempts. Type 'stop' to give up.")
def check(msg):
return msg.author == ctx.author and msg.channel == ctx.channel
Entry = 0
ran_picker = random.randrange(range_1, range_2)
while Entry <= attempt:
msg = await client.await_for('message', check=check)
Entry = Entry + 1
if msg.content == "stop" or msg.content == "Stop":
await ctx.send(f"You gave up 😢")
await ctx.send(f"The number was **{ran_picker}**")
break
elif int(msg.content) == ran_picker:
await ctx.send(f"**Good job, it was {ran_picker}!**")
break
elif int(msg.content) > range_2 or int(msg.content) < range_1:
await ctx.send(f"Pick a number between **{range_1}-{range_2}**!")
Entry = Entry - 1
print(Entry)
elif Entry == attempt:
await ctx.send(f"You ran out of inputs, it was **{ran_picker}**!")
break
else:
await ctx.send(f"Nope, keep guessing", delete_after=2)
except Exception as error:
print(f"{error}")
await ctx.send(f"Problem: **[{error}]**")re
In fact, other commands that's inside a cog folder involving the function/line
msg = await client.await_for('message', check=check)
# specifically' client.await_for'
I get a similar error.
I am fairly new to Python's language and Discord.py. I tried to read some of the documents for discord.py revolving around "setup_hooktype" and try to see how I can implement it into my code. Every time I change something I get a new error saying: "unexpected keyward argument," "no attributes" and so on. I believe this function has to do with the subclass (which I have for the cog) but I'm not sure how to create an addon for "setup_hook." I could just leave this command in my main.py, but soon or later I'm going to encounter this problem again in the future.
Any help is appreciated, thanks!
I'm making a Discord bot with Python that's basically an all-in-one bot. One of the features it has is a slot machine system, as part of its economy system. I have already worked out all the logic for the slot machine. My code is really long, so I'm only going to show the slot machine's function:
#bot.command(name="slots")
async def slots(ctx, amount = None):
await open_account(ctx.author)
if amount == None:
await ctx.send("Kid you gotta bet some actual omegas (bob's currency)")
return
bal = await update_bank(ctx.author)
amount = int(amount)
if amount > bal[0]:
await ctx.send("Imaginary omegas don't work here sunny boi, you don't have enough omegas for that transaction")
return
if amount < 0:
await ctx.send("Did ya ever learn about money in school? Give a positive value")
return
final = []
for i in range(3):
a = random.choice([":apple:", ":banana:", ":watermelon:"])
final.append(a)
for i in final:
realfinal = str(final).replace("[", " ")
for j in realfinal:
realREALfinal = str(realfinal).replace("]", " ")
for k in realREALfinal:
absfinal = str(realREALfinal).replace("'", " ")
for l in absfinal:
finalfinal = str(absfinal).replace(",", " | ")
slotem = discord.Embed(title=str(finalfinal), color=0xff9966)
slotem.add_field(name="SLOT MACHINE", value="Let's see if ya win kid")
await ctx.send(embed=slotem)
if final[0] == final[1] or final[0] == final[2] or final[1] == final[2]:
await update_bank(ctx.author, 2*amount, "pocket")
slotwinem = discord.Embed(title=f"Good job kid, you won `Ω{2*amount}`", color=0xccff66)
await ctx.send(embed=slotwinem)
elif final[0] == final[1] == final[2]:
await update_bank(ctx.author, 3*amount, "pocket")
slotallwinem = discord.Embed(title=f"Wow, sweet victory kid, you got `Ω{3*amount}`", color=0xccff66)
await ctx.send(embed=slotallwinem)
else:
await update_bank(ctx.author, -1*amount, "pocket")
slotloseem = discord.Embed(title=f"Oooh, tough luck kid- you lost `Ω{amount}`", color=0xff3300)
await ctx.send(embed=slotloseem)
This code is definitely extremely inefficient, but it works for now. What I want to do is for the slot machine to look like a real slot machine. To be more specific, I want the embed to be edited so all the emojis look like they are scrolling through all the choices. After two seconds, the first emoji scrolling stops and falls into place. After another two seconds, the second emoji falls into its place. After another two seconds, the third emoji falls into place. For example, this is a visual representation of what I mean: https://th.bing.com/th/id/Rd55e38b55c9ae007a4ffa1c5616bccd5?rik=iQ6wFZblIMc4pQ&pid=ImgRaw
How could I replicate this in Discord.py? Thanks.
elif "!bingo" in message.content.lower():
await message.channel.send("Here's your miniature Bingo sequence")
shuffled = shuffle(bingo)
await message.channel.send(bingo[0:3])
await message.channel.send(bingo[3:6])
await message.channel.send(bingo[6:9])
channel = message.channel
while userinput != "bingo":
await message.channel.send("Type anything to move on, or type bingo to end!")
def check(m):
return m.channel == channel
userinput[0](str(m.content))
if message.author == client.user:
return
else:
msg = await client.wait_for('message', check=check)
if str(userinput) == "bingo":
break
else:
await message.channel.send(random.randint(1,9))
The function is supposed to break when you input bingo, but for some reason the userinput string doesn't have any value. It is defined earlier on in the code, so it's not the cause of the problem.
Please help thanks
def check(m):
return m.channel == channel
userinput[0](str(m.content))
The second part is never executed as you always return with the first statement.
So userinput is never set to m.content as intended.
Pretty simple answer:
if str(userinput) == "bingo":
return
break is suppossed to be used to exit a function. And it doesn't work that well at it's designed job anyway.
Sorry if I am wrong, I am pretty new to discord.py, but I am not new to Python. Discord.py may be changing something to do with Python. If this doesn't work, sadly, I probably won't be able to help you.
I am trying to make a command which activates a random number guesser game. Obviously, I am stuck in the first few lines. I have written what I THINK will work, however it may be blatantly wrong. I want it to change the message on the discord server to an int, so it will work in my if statement.
It's my first time making a bot in with discord.py, so I am running into many obstacles. I am not fully sure what the error is telling me, so I haven't been able to try any fixes. This is the code:
async def numgame(context):
number = random.randint(1,100)
for guess in range(0,5):
await context.send('Pick a number between 1 and 100')
Message = await client.wait_for('message')
Message = int(Message)
if Message.cleant_content > number:
await context.send(guess + ' guesses left...')
asyncio.sleep(1)
await context.send('Try going lower')
asyncio.sleep(1)
elif Message.clean_content < number:
await context.send(guess + ' guesses left...')
asyncio.sleep(1)
await context.send('Try going higher')
asyncio.sleep(1)
else:
await context.send('You guessed it! Good job!')
if number != Message:
await context.send('Tough luck!')
Whenever I do the command in my discord server, my shell gives me this error:
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: int() argument must be a string, a bytes-like object or a number, not 'Message'
I am not too sure what it is telling me. As stated, I would like "Message" to be an integer, but I get the error. but help would be appreciated!
[still a beginner, don't be too harsh :(]
wait_for('message') returns a Message object, which int doesn't know how to handle yet. You need to convert Message.content to an int instead. Just below is your code with some other changes:
def check(message):
try:
int(message.content)
return True
except ValueError:
return False
#bot.command()
async def numgame(context):
number = random.randint(1,100)
for guess in range(0,5):
await context.send('Pick a number between 1 and 100')
msg = await client.wait_for('message', check=check)
attempt = int(msg.content)
if attempt > number:
await context.send(str(guess) + ' guesses left...')
await asyncio.sleep(1)
await context.send('Try going lower')
await asyncio.sleep(1)
elif attempt < number:
await context.send(str(guess) + ' guesses left...')
await asyncio.sleep(1)
await context.send('Try going higher')
await asyncio.sleep(1)
else:
await context.send('You guessed it! Good job!')
break
else:
await context.send("You didn't get it")
I am trying to build up discord bot through pip discord.py. After command !random I want to ask user for any number and bot will then generate random number between 0 and entered number. It doesn't rly work for me and because i don't know much things about discord.py, I ask there :)
code:
import random
elif message.content.startswith("!random"):
await client.send_message(message.channel, "Enter a number: ")
num = await client.wait_for_message(int)
numm = int(num)
randomnum = random.randint(0, numm)
await client.send_message(message.channel, randomnum)
Try this:
import random
elif message.content.startswith("!random"):
await client.send_message(message.channel, "Enter a number: ")
def check(msg):
return msg.content
reaction.content = await client.wait_for_message(author=message.author, check=check)
numm = int(reaction)
randomnum = random.randint(0, numm)
await client.send_message(message.channel, randomnum)
You should also check if the reaction is a int
(added squaswin's reaction. note that the code is not tested)