You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 17:54:25