Reputation: 3
I'm making a dice roller Discord bot qith Python 3. The die number looks up a phrase in a dictionary and the outputs it. I had it fine working with a six sided die, but I want the user to be able to make it a 10 sided die instead.
To roll a die it is '!y1' to set it to 10 sided die it's '!y d10'. I tied setting it to d6 by default, however when I try rolling now it gives me an error of the variable being undefined. Could someone help point me to what I am missing?
import os
from random import randint
import discord
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
client = discord.Client()
def ybna6_faces(x):
return{
1: 'Yes, And...',
2: 'Yes...',
3: 'Yes, But...',
4: 'No, But...',
5: 'No...',
6: 'No, And...'
}[x]
def danger6_faces(x):
return{
1: 'Blank',
2: 'Blank',
3: 'Blank',
4: 'Blank',
5: 'Skull!',
6: 'Two Skull!!'
}[x]
def ybna10_faces(x):
return{
1: 'Yes, And...',
2: 'Yes...',
3: 'Yes, But...',
4: 'No, But...',
5: 'No...',
6: 'No, And...',
7: '',
8: '',
9: '',
10: ''
}[x]
def danger10_faces(x):
return{
1: 'Blank',
2: 'Blank',
3: 'Blank',
4: 'Blank',
5: 'Skull!',
6: 'Two Skull!!',
7: '',
8: '',
9: '',
10: ''
}[x]
sides = 6
#active_ybna = 6
#active_danger = 6
w=""
#Successful server connection message
@client.event
async def on_ready():
print(f'{client.user.name} has connected to Discord!')
#Makes sure bot doesn't respond to itself
@client.event
async def on_message(message):
if message.author == client.user:
return
#Choose die (6 or 10)
if message.content.startswith('!y d6'):
sides = 6
if message.content.startswith('!y d10'):
sides = 10
#Evaluate rolls
if message.content.startswith('!y'):
if int(message.content[2])>int(0):
z = int(message.content[2])
for x in range(z):
y = randint(1,int(sides))
active_ybna = 'ybna'+ sides + '_faces()'
response = 'Roll ' + str(x+1) + ': ' + active_ybna(y)
await message.channel.send(response)
if len(message.content)>=4:
if int(message.content[4])>int(0):
z = int(message.content[4])
for x in range(z):
y=randint(1,int(sides))
active_danger = 'danger'+ sides + '_faces()'
response = 'Danger ' + str(x+1) + ': ' + active_danger(y)
await message.channel.send(response)
client.run(TOKEN)
EDIT: Traceback on input of '!y1'
YBNA Bot has connected to Discord!
Ignoring exception in on_message
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.7/site-packages/discord/client.py", line 312, in _run_event
await coro(*args, **kwargs)
File "/home/pi/Desktop/discord bots/ybnabot.py", line 92, in on_message
y = randint(1,int(sides))
UnboundLocalError: local variable 'sides' referenced before assignment
Upvotes: 0
Views: 1313
Reputation: 3
I think my issued was variables not declared Global. I kinda simplified it all and tucked it into one event with multiple IF's.
Some other code added as well...
# ybnabot.py
#d6 functionality
import os
from random import randint
import discord
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
client = discord.Client()
def ybna6_faces(x):
return{
1: 'No, And...',
2: 'No...',
3: 'No, But...',
4: 'Yes, But...',
5: 'Yes...',
6: 'Yes, And...'
}[x]
def danger6_faces(x):
return{
1: 'Blank',
2: 'Blank',
3: 'Blank',
4: 'Blank',
5: ':skull:',
6: ':skull: :skull:'
}[x]
def ybna10_faces(x):
return{
1: 'No, And...',
2: 'No, And, But...',
3: 'No...',
4: 'Not, But...',
5: 'No, But, And...',
6: 'Yes, But, And...',
7: 'Yes, But...',
8: 'Yes...',
9: 'Yes, And, But...',
10: 'Yes, And...'
}[x]
def danger10_faces(x):
return{
1: 'Blank',
2: 'Blank',
3: 'Blank',
4: 'Blank',
5: ':skull',
6: ':skull: :skull',
7: 'Blank',
8: 'Blank',
9: ':skull:',
10: ':skull: :skull:'
}[x]
@client.event
async def on_ready():
global sides
sides = 6
print(f'{client.user.name} has connected to Discord!')
@client.event
async def on_message(message):
global sides
if message.author == client.user:
return
#Send Help DM
if message.content.startswith('!y help'):
await message.author.send('YBNA Bot Help!')
await message.author.send('Commands:')
await message.author.send('!y X Z - Roll X number of YBNA dice and Z Danger dice (Danger die can be omitted)')
await message.author.send('!y d6 - Choose six sided dice')
await message.author.send('!y d10 - Choose 10 sided dice')
await message.author.send('!y dice - Displays which dice are selected (d6 or d10)')
await message.author.send('!y help - This message!')
await message.author.send('txutfz73 credits here')
await message.author.send('github link here')
return
#Check die used
if message.content.startswith('!y dice'):
response = 'Using ' + str(sides) + ' sided dice!'
await message.channel.send(response)
return
#Choose d6 or d10
if message.content.startswith('!y d6'):
sides = 6
await message.channel.send('Now using d6!')
return
if message.content.startswith('!y d10'):
sides = 10
response = 'Now using d10!'
await message.channel.send(response)
return
#Roll d6
if sides == 6:
if message.content.startswith('!y'):
if int(message.content[2])>int(0):
z = int(message.content[2])
for x in range(z):
y = randint(1,6)
response = 'Roll ' + str(x+1) + ': ' + ybna6_faces(y) + str(sides)
await message.channel.send(response)
if len(message.content)>=4:
if int(message.content[4])>int(0):
z = int(message.content[4])
for x in range(z):
y=randint(1,6)
response = 'Danger ' + str(x+1) + ': ' + danger6_faces(y)
await message.channel.send(response)
#Roll d10
else:
if message.content.startswith('!y'):
if int(message.content[2])>int(0):
z = int(message.content[2])
for x in range(z):
y = randint(1,10)
response = 'Roll ' + str(x+1) + ': ' + ybna10_faces(y) + str(sides)
await message.channel.send(response)
if len(message.content)>=4:
if int(message.content[4])>int(0):
z = int(message.content[4])
for x in range(z):
y=randint(1,10)
response = 'Danger ' + str(x+1) + ': ' + danger10_faces(y)
await message.channel.send(response)
client.run(TOKEN)
Upvotes: 0
Reputation: 3497
You have two if
statements that can both evaluate to False
, meaning it is possible the sides
variable is never created.
This is because the sides
you create is outside the function, making it out of scope. You need to move this inside the function or declare sides
as global (not advised).
...
#active_ybna = 6
#active_danger = 6
w=""
#Successful server connection message
@client.event
async def on_ready():
print(f'{client.user.name} has connected to Discord!')
#Makes sure bot doesn't respond to itself
@client.event
async def on_message(message):
sides = 6
if message.author == client.user:
return
#Choose die (6 or 10)
if message.content.startswith('!y d6'):
sides = 6
if message.content.startswith('!y d10'):
sides = 10
#Evaluate rolls
if message.content.startswith('!y'):
if int(message.content[2])>int(0):
z = int(message.content[2])
for x in range(z):
y = randint(1,int(sides))
active_ybna = 'ybna'+ sides + '_faces()'
response = 'Roll ' + str(x+1) + ': ' + active_ybna(y)
await message.channel.send(response)
if len(message.content)>=4:
if int(message.content[4])>int(0):
z = int(message.content[4])
for x in range(z):
y=randint(1,int(sides))
active_danger = 'danger'+ sides + '_faces()'
response = 'Danger ' + str(x+1) + ': ' + active_danger(y)
await message.channel.send(response)
client.run(TOKEN)
Upvotes: 1