如何用discord.py实现余额命令?求助搭建投注游戏货币系统
实现Discord机器人的货币系统与余额命令
嘿,别用纯TXT文件来记录成员数据啦——这真的不是个好选择!TXT完全没有结构化设计,读写效率低,碰到多个用户同时操作的时候还容易出现数据错乱的问题。更推荐用结构化的存储方式,比如Python内置的sqlite3数据库(不用额外装依赖,轻量又好用),或者JSON文件(比TXT好维护太多)。下面给你一步步拆解实现方案:
一、用SQLite3构建货币系统(最推荐长期使用)
SQLite是轻量级的本地数据库,特别适合小型Discord机器人,不需要额外部署,直接就能用。
1. 先初始化数据库
在机器人启动时创建一个存储用户余额的表:
import discord from discord.ext import commands import sqlite3 # 初始化机器人,记得开启必要的intents bot = commands.Bot(command_prefix="!", intents=discord.Intents.all()) def init_database(): # 连接(不存在则创建)名为economy.db的数据库 conn = sqlite3.connect("economy.db") cursor = conn.cursor() # 创建用户表:用户ID(唯一标识)、余额(默认100初始币)、注册时间 cursor.execute('''CREATE TABLE IF NOT EXISTS users (user_id INTEGER PRIMARY KEY, balance INTEGER DEFAULT 100, join_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP)''') conn.commit() conn.close() @bot.event async def on_ready(): init_database() print(f"✅ 机器人已登录:{bot.user}")
2. 写核心工具函数
封装几个常用的数据库操作函数,方便后续命令调用:
def get_user_balance(user_id): conn = sqlite3.connect("economy.db") cursor = conn.cursor() cursor.execute("SELECT balance FROM users WHERE user_id = ?", (user_id,)) result = cursor.fetchone() conn.close() # 如果用户是第一次使用,自动创建记录并返回初始余额 if not result: add_new_user(user_id) return 100 return result[0] def add_new_user(user_id): conn = sqlite3.connect("economy.db") cursor = conn.cursor() # 用INSERT OR IGNORE避免重复添加 cursor.execute("INSERT OR IGNORE INTO users (user_id) VALUES (?)", (user_id,)) conn.commit() conn.close() def update_user_balance(user_id, amount): conn = sqlite3.connect("economy.db") cursor = conn.cursor() # 确保用户存在后再更新余额 add_new_user(user_id) cursor.execute("UPDATE users SET balance = balance + ? WHERE user_id = ?", (amount, user_id)) conn.commit() conn.close()
3. 实现余额查询命令
做一个支持查询自己或他人余额的命令,用Embed让消息更美观:
@bot.command(name="balance", aliases=["bal", "余额"]) async def check_balance(ctx, member: discord.Member = None): # 默认查询自己,指定成员则查询对方 target_user = member or ctx.author user_balance = get_user_balance(target_user.id) embed = discord.Embed( title=f"💸 {target_user.display_name} 的余额", description=f"当前持有:**{user_balance}** 硬币", color=discord.Color.green() ) embed.set_thumbnail(url=target_user.display_avatar.url) await ctx.send(embed=embed)
二、如果想试试轻量的JSON方案
要是你暂时不想碰数据库,JSON文件比TXT友好太多,结构化存储,读写也简单:
1. 初始化JSON文件
import json import os def init_economy_json(): if not os.path.exists("economy.json"): # 初始为空字典 with open("economy.json", "w", encoding="utf-8") as f: json.dump({}, f, indent=4) @bot.event async def on_ready(): init_economy_json() print(f"✅ 机器人已登录:{bot.user}")
2. 工具函数与余额命令
def get_balance_json(user_id): with open("economy.json", "r", encoding="utf-8") as f: data = json.load(f) # 不存在则返回初始100币 return data.get(str(user_id), 100) def update_balance_json(user_id, amount): with open("economy.json", "r", encoding="utf-8") as f: data = json.load(f) user_str = str(user_id) # 新用户自动初始化余额 if user_str not in data: data[user_str] = 100 data[user_str] += amount # 写入更新后的数据 with open("economy.json", "w", encoding="utf-8") as f: json.dump(data, f, indent=4, ensure_ascii=False) @bot.command(name="balance", aliases=["bal", "余额"]) async def check_balance(ctx, member: discord.Member = None): target_user = member or ctx.author user_balance = get_balance_json(target_user.id) await ctx.send(f"💸 {target_user.display_name} 的余额:**{user_balance}** 硬币")
三、扩展到你的投注游戏
有了货币系统,投注游戏的逻辑就顺理成章了,举个简单的骰子投注例子:
import random @bot.command(name="bet", aliases=["投注"]) async def dice_bet(ctx, amount: int, guess: int): # 基础校验 if amount <= 0: await ctx.send("⚠️ 投注金额必须大于0哦!") return user_balance = get_user_balance(ctx.author.id) if user_balance < amount: await ctx.send("❌ 你的余额不够啦!") return if guess not in range(1,7): await ctx.send("⚠️ 请猜1-6之间的数字哦!") return # 掷骰子 dice_result = random.randint(1,6) if dice_result == guess: # 猜中,奖励等额投注金额(净赚1倍) update_user_balance(ctx.author.id, amount) await ctx.send(f"🎉 恭喜你猜中了!骰子点数是{dice_result},你获得了{amount}硬币!当前余额:{get_user_balance(ctx.author.id)}") else: # 没猜中,扣除投注金额 update_user_balance(ctx.author.id, -amount) await ctx.send(f"😢 很遗憾没猜中,骰子点数是{dice_result},你损失了{amount}硬币!当前余额:{get_user_balance(ctx.author.id)}")
最后再强调下:真的别用纯TXT,你得自己处理数据拆分、格式维护,还要担心并发写入冲突,太折腾了。上面两种方案都比TXT靠谱,尤其是SQLite,后续要加交易记录、等级系统之类的扩展也很方便。
内容的提问来源于stack exchange,提问作者Pepe
相关产品推荐
相关产品推荐

