基于pycord的Discord自定义卡牌机器人防重复发牌咨询
解决方案:本地文件夹随机不重复发牌
核心思路是维护一个已发卡牌的记录集合,每次发牌时从本地文件夹的卡牌中排除已发的,再随机选取。以下是具体实现步骤和代码:
1. 基础实现(非持久化)
适合临时运行,机器人重启后已发记录会清空:
import os import random import discord from discord.ext import commands bot = commands.Bot(command_prefix="-", intents=discord.Intents.all()) # 跟踪已发卡牌的文件名集合 issued_cards = set() # 替换为你的本地卡牌文件夹路径 CARD_FOLDER = "./cards" @bot.command() async def hand(ctx, name: str): # 获取文件夹内所有卡牌文件(过滤掉子文件夹) all_cards = [ filename for filename in os.listdir(CARD_FOLDER) if os.path.isfile(os.path.join(CARD_FOLDER, filename)) ] # 筛选出未发的卡牌 available_cards = [card for card in all_cards if card not in issued_cards] if not available_cards: await ctx.send(f"{name},所有卡牌已发完,无法继续发牌!") return # 随机选一张未发的卡牌 selected_card = random.choice(available_cards) issued_cards.add(selected_card) # 发送卡牌文件(支持图片、文档等Discord支持的格式) card_file_path = os.path.join(CARD_FOLDER, selected_card) await ctx.send(f"给{name}发牌:", file=discord.File(card_file_path)) # 替换为你的机器人Token bot.run("YOUR_BOT_TOKEN")
2. 持久化已发记录(重启不丢失)
如果需要机器人重启后保留已发牌记录,可以把集合数据写入本地文件:
import os import random import json import discord from discord.ext import commands bot = commands.Bot(command_prefix="-", intents=discord.Intents.all()) CARD_FOLDER = "./cards" # 存储已发牌记录的文件路径 ISSUED_RECORD_FILE = "./issued_cards.json" # 加载已发牌记录 def load_issued_cards(): if os.path.exists(ISSUED_RECORD_FILE): with open(ISSUED_RECORD_FILE, "r", encoding="utf-8") as f: return set(json.load(f)) return set() # 保存已发牌记录 def save_issued_cards(cards_set): with open(ISSUED_RECORD_FILE, "w", encoding="utf-8") as f: json.dump(list(cards_set), f) # 初始化已发牌集合 issued_cards = load_issued_cards() @bot.command() async def hand(ctx, name: str): all_cards = [ filename for filename in os.listdir(CARD_FOLDER) if os.path.isfile(os.path.join(CARD_FOLDER, filename)) ] available_cards = [card for card in all_cards if card not in issued_cards] if not available_cards: await ctx.send(f"{name},所有卡牌已发完,无法继续发牌!") return selected_card = random.choice(available_cards) issued_cards.add(selected_card) # 保存更新后的记录 save_issued_cards(issued_cards) card_file_path = os.path.join(CARD_FOLDER, selected_card) await ctx.send(f"给{name}发牌:", file=discord.File(card_file_path)) # 管理员重置命令(可选) @bot.command() @commands.has_permissions(administrator=True) async def resetcards(ctx): global issued_cards issued_cards.clear() save_issued_cards(issued_cards) await ctx.send("已重置所有已发卡牌记录!") bot.run("YOUR_BOT_TOKEN")
关键注意点
- 确保
CARD_FOLDER路径正确,文件夹内只放卡牌文件,避免混入无关文件 - 持久化方案会生成
issued_cards.json文件,不要手动删除或修改该文件 - 如果卡牌文件有分类需求,可以在代码中添加文件名过滤逻辑(比如只选
.png格式的图片)
内容的提问来源于stack exchange,提问作者Hannah Horn
相关产品推荐
相关产品推荐

