对于我的机器人,我想实现随机游戏(例如抛硬币),以及在此之上的投注系统。 例如,任何人都可以使用 //coin_toss 并且机器人会回答“正面”或“尾巴”,但是如果命令是 //bet 15 coin_toss,机器人也会回答“正面”或“尾巴”,但也会在“恭喜你赢了 X " 或 "你输了"。
@commands.command()
async def coin_toss(self, ctx: Context):
outcomes = ("Heads", "Tails")
result = outcomes[random.randint(0,1)]
await ctx.reply(result)
return result
问题是我希望 //coin_toss 命令没有可以通过调用命令传递的参数,但我仍然希望通过 self.coin_toss(ctx, amount_to_bet=5) 调用它时传递参数例子。这也适用于调用 self.coin_toss
command: Command = utils.get(self.get_commands(), name=game_name)
result = await command(ctx, amount_to_bet)
现在我使用 *args 来“收集”用户试图传递的所有参数,但我不知道在通过频道中的消息调用命令时是否可以绕过。
@commands.command(aliases=["pile_ou_face", "pof"])
@has_user_role_from_config()
async def coin_toss(self, ctx: Context, *args, amount_to_bet: float = 0):
outcomes = ("Heads", "Tails")
result = outcomes[random.randint(0,1)]
await ctx.reply(result)
return result
有没有办法做到这一点?如果您想要更精确,请随时发表评论
答案 0 :(得分:1)
我不确定这是否能回答您关于隐藏不和谐命令参数的问题,但我认为它可能会给您一些关于如何根据其他游戏命令实施 bet
命令而无需需要做这么多的参数解析。
我有两个建议。将 coin_toss 视为下注函数的子例程或实现 coin_toss 函数的共享逻辑实现。
import os
import random
from discord.ext import commands
from dotenv import load_dotenv
load_dotenv()
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
bot = commands.Bot(command_prefix="//")
@bot.command()
async def coin_toss(ctx):
outcomes = ("Heads", "Tails")
result = outcomes[random.randint(0, 1)]
await ctx.reply(result)
return result
# Simulates your Utils Get Function
def get_commands():
return [coin_toss]
def get_command_by_name(command_list, name):
names = [c.name for c in command_list]
if name not in names:
return None
else:
return command_list[names.index(name)]
@bot.command()
async def bet(ctx, *args):
if len(args) != 3:
# Example //bet 15 Heads coin_toss
await ctx.reply("Command is //bet amount outcome game_name")
c = get_command_by_name(get_commands(), name=args[2])
# Check Command Exists
if c is None:
await ctx.reply(f"Command {args[2]} does not exist")
else:
# Assumes result comes back as a string!!
result = await c(ctx)
# Compare case insensitive
if result.lower() == args[1].lower():
msg = f"Congratulation you won {args[0]}"
else:
msg = f'You lost your bet of {args[0]}'
await ctx.reply(msg)
bot.run(DISCORD_TOKEN)
我在这里模拟了您的 get_commands
和 utils.get(self.get_commands(), name=value)
函数,因此请更新您的 bet
实现以反映您的函数实际执行情况。为了便于测试,我也在课堂之外完成了这项工作,但请进行必要的更改以将此代码合并到您当前的实现中。
这种方法的缺点是延迟。您发送了两个单独的回复,一次来自 coin_toss
函数,然后再次来自 bet
,这可能会延迟用户体验。
import os
import random
from discord.ext import commands
from dotenv import load_dotenv
load_dotenv()
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
bot = commands.Bot(command_prefix="//")
# Separated Game Logic from the Bot Command
def coin_toss_logic():
outcomes = ("Heads", "Tails")
result = outcomes[random.randint(0, 1)]
return result
@bot.command()
async def coin_toss(ctx):
await ctx.reply(coin_toss_logic())
# Simulates your Utils Get Function
def get_commands():
return [coin_toss_logic]
def get_command_by_name(command_list, name):
# Strip off the "_logic" portion of your command names
# uses __name__ since not a command anymore
# Requires a consistent naming convention!
names = [c.__name__[:-6] for c in command_list]
if name not in names:
return None
else:
return command_list[names.index(name)]
@bot.command()
async def bet(ctx, *args):
if len(args) != 3:
# Example //bet 15 Heads coin_toss
await ctx.reply("Command is //bet amount outcome game_name")
c = get_command_by_name(get_commands(), name=args[2])
# Check Command Exists
if c is None:
await ctx.reply(f"Command {args[2]} does not exist")
else:
# Assumes result comes back as a string!!
# No await needed since it's not an asyc command
result = c()
# Need to add Result to msg since not handled by command anymore
msg = f'{result}\n'
# Compare case insensitive
if result.lower() == args[1].lower():
msg += f"Congratulation you won {args[0]}"
else:
msg += f'You lost your bet of {args[0]}'
await ctx.reply(msg)
bot.run(DISCORD_TOKEN)
这种实现的好处是消息之间的延迟更少,但是,由于您基本上有两个独立的函数,它们都映射到相同的名称,因此需要做更多的工作。