What I'm Trying to do: Make a hangman game using discord.py-rewrite
My Problem: The code stops working after the bot sends (Fruits Category) or (Animals Category) etc. There are no error messages either. I've tried changing def to async def to try to use await ctx.send, but to no avail.
#client.command()
async def hangman(ctx, category):
fruits = ['pear', 'banana', 'apple']
animals = ['cat', 'horse', 'turtle']
userGuesslist = []
userGuesses = []
playGame = True
category = category
continueGame = "Y"
name = ctx.message.author.mention
await ctx.send(f"Welcome to hangman {name}!")
time.sleep(2)
await ctx.send("Your Objective:tm:: Find my secret word from the category you chose")
time.sleep(2)
await ctx.send("Don't forget that you can only guess with letters!")
time.sleep(2)
await ctx.send(f"Good luck {name}!")
while True:
while True:
if category.upper() == 'F':
await ctx.send("__**Fruits Category**__")
secretWord = random.choice(fruits)
break
elif category.upper() == 'A':
await ctx.send("__**Animals Category**__")
secretWord = random.choice(animals)
break
else:
await ctx.send("__**Random Category**__")
secretWord = random.choice(fruits, animals)
break
if playGame:
secretWordList = list(secretWord)
attempts = (len(secretWord) + 2)
def pGuessedLetter():
("Your Secret word is: "+ ''.join(userGuessList))
for n in secretWordList:
userGuesslits.append('\_ ')
pGuessedLetter()
await ctx.send(f"Number of allowed guesses for this word: {attempts}")
while True:
await ctx.send("**Guess a letter:**")
def check(m):
return m.content and user == ctx.message.author
letter = check
if letter in userGuesses:
await ctx.send("You already guessed this letter, try something else")
else:
attempts -= 1
userGuesses.append(letter)
if letter in secretWordList:
await ctx.send("Nice guess!")
if attemps > 0:
await ctt.send(f"Attempts left: {attempts}")
for i in range(len(secretWordList)):
if letter == secretWordList[i]:
letterIndex = i
userGuesslits[letterIndex] = letter.upper()
pGuessedLetter()
else:
await ctx.send("Nope, try again :eye: :eye:")
if attempts > 0:
await ctx.send(f"Attempts left: {attempts}")
pGuessedLetter()
joinedList = ''.join(userGuesslist)
if joinedList.upper() == secretWord.upper():
await ctx.send(f"You got it {name}! The word was {secretWord}")
break
elif attempts == 0:
await ctx.send(f"Too many Guesses! Better luck next time {name}")
await ctx.send(f"The secret word was {secretWord.upper()}")
break
#hangman.error
async def hangman_error(ctx, error):
if isinstance(error, discord.ext.commands.errors.MissingRequiredArgument):
await ctx.send("""Ensure you include a category:
**Example:** `bl!hangman A`
`F - Fruits`
`A - Animals`
`X - Cancel`
""")
I wouldn't recommend to use while loops!
Use await client.wait_for('message') instead. (https://discordpy.readthedocs.io/en/latest/api.html?highlight=wait_for#discord.Client.wait_for)
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!
trying to make a nice embed for my diceroll command to output to but my issue is that the embed keeps just displaying raw value rather than the int value i'm trying to get (image for reference bellow) i’ve tried to find workarounds or solutions online but cant find anything that works or is specific to my issue
#bot.command()
async def rolldice(ctx):
messagetwo = await ctx.send("Choose a number:\n**4**, **6**, **8**, **10**, **12**, **20** ")
user = ctx.message.author.display_name
def check(m):
return m.author == ctx.author
try:
messageone = await bot.wait_for("message", check = check, timeout = 30.0)
m = messageone.content
if m != "4" and m != "6" and m != "8" and m != "10" and m != "12" and m != "20":
await ctx.send("Sorry, invalid choice.")
return
coming = await ctx.send("Here it comes...")
asyncio.sleep(1)
await coming.delete()
await messagetwo.delete()
await ctx.channel.purge(limit=2)
embedVar = discord.Embed(title="{user}'s Dice",color=0x00ffff)
embedVar.add_field(name="rolled", value="D{m}", inline=True)
embedVar.add_field(name="landed", value="{random.randint(1, int(m))}", inline=True)
embedVar.set_footer(text='Booty Police | Dungeon Dice',icon_url="http://canvaswrite.com/PI/pybot/attachments/server-icon-full.png")
await ctx.send(embed=embedVar)
await ctx.send(f"{user} rolled a **D{m}** and got a **{random.randint(1, int(m))}**")
except asyncio.TimeoutError:
await messageone.delete()
await ctx.send("Procces has been canceled because you didn't respond in **30** seconds.")
I think you are trying to use f-string but forgot to place the f before the string. Without the f it will not format the string. Here's a guide on f-strings if you want to read more about them
x = 3
print(f"This is the value {x}")
>>> This is the value 3
so in order for your code to work you need to just prepend the string with an f. the fixed code would look something like this:
#bot.command()
async def rolldice(ctx):
messagetwo = await ctx.send("Choose a number:\n**4**, **6**, **8**, **10**, **12**, **20** ")
user = ctx.message.author.display_name
def check(m):
return m.author == ctx.author
try:
messageone = await bot.wait_for("message", check = check, timeout = 30.0)
m = messageone.content
if m != "4" and m != "6" and m != "8" and m != "10" and m != "12" and m != "20":
await ctx.send("Sorry, invalid choice.")
return
coming = await ctx.send("Here it comes...")
asyncio.sleep(1)
await coming.delete()
await messagetwo.delete()
await ctx.channel.purge(limit=2)
embedVar = discord.Embed(title=f"{user}'s Dice",color=0x00ffff)
embedVar.add_field(name="rolled", value=f"D{m}", inline=True)
embedVar.add_field(name="landed", value=f"{random.randint(1, int(m))}", inline=True)
embedVar.set_footer(text='Booty Police | Dungeon Dice',icon_url="http://canvaswrite.com/PI/pybot/attachments/server-icon-full.png")
await ctx.send(embed=embedVar)
await ctx.send(f"{user} rolled a **D{m}** and got a **{random.randint(1, int(m))}**")
except asyncio.TimeoutError:
await messageone.delete()
await ctx.send("Procces has been canceled because you didn't respond in **30** seconds.")
I want to make disposable register system by using list which makes adding the discord user to list when you mentioned it but when i try to get user input from message it fails
#bot.command()
async def gameset(ctx,playernum:int):
if playernum <= 10:
await ctx.send('player 1 "<assign #player" mention yourself like this!')
else:
await ctx.send('maximum 10 player!')
num = 1
while num < playernum:
playerlist = []
#bot.command()
async def assign(user):
if user == discord.User.mentioned_in(message=user):
listadd = user
playerlist.append(listadd)
await user.send(f"player {num + 1} mention yourself!")
elif user != discord.User:
await user.send("not user")
else:
await user.send("go fix it dumb")
if playerlist[num - 1] == discord.User:
num = num + 1
else:
await gameset.send("problem with the listing")
also i think this is not the only problem i tried like this too but then my mention/user percaption logic failed i think
#bot.command()
async def ata(user : discord.User):
if not user:
await user.send("go fix it dumb")
else:
listadd = user
playerlist.append(listadd)
await user.send(f"player {num + 1} mention yourself!")
I've tried with #bot.event but i made more progress with #bot.command so if this is able to do with #bot.event i would be pleased if you guys help me understand how can i do with event but command is sufficient too.
Edit: I tried using wait_for() command like this:
num = 1
while num < playernum:
playerlist = []
def check(msg2 : discord.member):
return msg2 == discord.mentions
msg2 = await bot.wait_for("message", check=check)
# player = await bot.fetch_member(msg2.id)
if msg2 == discord.member:
player = str(msg2.id)
listadd = player
playerlist.append(listadd)
await ctx.send(f"player {num + 1} mention yourself!")
num = num + 1
else:
await msg2.send("go fix it dumb")
and i think it worked but now i have another problem which is
discord.ext.commands.errors.CommandNotFound: Command "#!id>" is not found
i get this when i try to mention someone
#client.command()
async def blackjack(ctx):
y= random.choice(deck)
x=random.choice(deck)
z=random.choice(deck)
a=random.choice(deck)
await ctx.send(f'{x, y}')
await ctx.send(f'{a, z}')
m = await client.wait_for("message", check=None)
if m == "Stand":
B = x+y
S = a+z
if S < B:
while S < B or S < 21:
await ctx.send(S= a+z+random.choice(deck))
if S > 21:
ctx.send("You win")
else:
ctx.send("You Lose")
else:
ctx.send("You Lose")
This is a snippet of my code where I'm trying to get user input on whether he wants to stand or draw another card. I have not yet implemented a draw feature as the stand feature does not seem to work. My deck is properly defined as numbers and.
I think the problem is in the user input as I'm not very familiar with input in discord.py
if the program would work it would wait for the user's response if they want to stand and draw cards until it has over 21 or has more than the player and print out whether the player has lost or won.
Any help would be appreciated
I think you didn't add the check you kept it NONE.
so you should do it like this:
#client.command()
async def blackjack(ctx):
y= random.choice(deck)
x=random.choice(deck)
z=random.choice(deck)
a=random.choice(deck)
await ctx.send(f'{x, y}')
await ctx.send(f'{a, z}')
def check(msg):
return msg.author == ctx.author and msg.channel == ctx.channel and msg.content.lower().startswith()
msg = await client.wait_for("message", check=check)
if msg.content.lower().startswith("Stand"):
B = x+y
S = a+z
if S < B:
while S < B or S < 21:
await ctx.send(S= a+z+random.choice(deck))
if S > 21:
ctx.send("You win")
else:
ctx.send("You Lose")
else:
ctx.send("You Lose")
The startswith() is purely optional but I recommend you to add it!
You can add event time out like this:
msg = await bot.wait_for("message", check=check, timeout=<anything you want in {int}>)
I was wondering how it is possible to get a bot status to switch
please help me because I'm new to coding discord bots and I don't know much and when I google it it doesn't work for me.
This is my code:
import keep_alive
import discord, os
from discord.ext import commands
import typing
import asyncio
import random
prefix="cs!"
client = commands.Bot(command_prefix=prefix)
def replaceSpaces(string):
string = string.strip()
i = len(string)
space_count = string.count(' ')
new_length = i + space_count * 2
if new_length > 1000:
return -1
index = new_length - 1
string = list(string)
for f in range(i - 2, new_length - 2):
string.append('0')
for j in range(i - 1, 0, -1):
if string[j] == ' ':
string[index] = '0'
string[index - 1] = '2'
string[index - 2] = '%'
index = index - 3
else:
string[index] = string[j]
index -= 1
return ''.join(string)
#client.event
async def on_ready():
await client.change_presence(activity=discord.Game(name="cs!help || made with <3 by Spoon#7194"))
#client.event
async def on_ready():
servers = len(client.guilds)
members = 0
for guild in client.guilds:
members += guild.member_count - 1
await client.change_presence(activity = discord.Activity(
type = discord.ActivityType.watching,
name = f'cs!help | {servers} Server {members} Member'
))
#client.event
async def on_message(message):
msg = message.content.lower()
if message.author == client.user:
return
elif msg.startswith("cs!hello"):
await message.channel.send(f"hello, {message.author}!")
elif msg.startswith("cs!help"):
await message.channel.send(f"commands: cs!hello, cs!replsearch <query>, cs!twitch <query>, cs!youtube <query>, cs!google <query>")
elif msg.startswith("cs!replsearch "):
resultr = msg.split('cs!replsearch ', 1)
if resultr[-1] == "":
await message.channel.send("Error :face_with_raised_eyebrow:, no query given")
elif msg.startswith("cs!replsearch"):
await message.channel.send("Error :face_with_raised_eyebrow:, no query given")
elif msg.startswith("cs!twitch "):
resultt = msg.split('cs!twitch ', 1)
if resultt[-1] == "":
await message.channel.send("Error :face_with_raised_eyebrow:, no query given")
else:
await message.channel.send(f"https://twitch.tv/search?term={replaceSpaces(resultt[-1])}")
elif msg.startswith("cs!twitch"):
await message.channel.send("Error :face_with_raised_eyebrow:, no query given")
elif msg.startswith("cs!youtube "):
resulty = msg.split('cs!youtube ', 1)
if resulty[-1] == "":
await message.channel.send("Error :face_with_raised_eyebrow:, no query given")
else:
await message.channel.send(f"https://www.youtube.com/results?search_query={replaceSpaces(resulty[-1])}")
elif msg.startswith("cs!youtube"):
await message.channel.send("Error :face_with_raised_eyebrow:, no query given")
elif msg.startswith("cs!google "):
result = msg.split('cs!google ', 1)
if result[-1] == "":
await message.channel.send("Error :face_with_raised_eyebrow:, no query given")
else:
await message.channel.send(f"https://www.google.com/search?q={replaceSpaces(result[-1])}")
elif msg.startswith("cs!google"):
await message.channel.send("Error :face_with_raised_eyebrow:, no query given")
elif msg.startswith("cs!"):
await message.channel.send("Error :face_with_raised_eyebrow:, not a valid command")
#server.server()#bot.command()
#async def token
#embed=discord.Embed(title="Help", description="description here")
#embed.add_field(name="Moderation commands", value="your commands here", inline=False)
#embed.add_field(name="Fun Commands", value="your commands here", inline=False)
#embed.set_footer(text="footer text")
#await ctx.send(embed=embed)
keep_alive.keep_alive()
client.run('{I deleted this part here}')
Change Your Status every x seconds
#discord.ext.tasks.loop(seconds=5)
async def change_p():
await client.wait_until_ready()
statuses = [f"{len(client.guilds)} Servers with {len(client.users)} Users!", "You Talk!",
"The Epic Server!"]
await client.change_presence(activity=discord.Activity(type=discord.ActivityType.watching, name=choice(statuses)))
change_p.start()
const status = "YOURSTATUS"
client.user.setActivity(status)
Also Try that :)