大乐透与刮刮乐插件
适配 monetary 的自定义积分彩票插件,提供群聊大乐透下注、开奖与奖池分配,并附带刮刮乐小游戏。
作者: 蜥蜴
背景
在运行于社群的聊天机器人中,积分制的娱乐玩法是常见的互动需求。若以线下方式组织大乐透类游戏,需要一位负责人完成以下工作:
- 记录每位参与者的下注金额与下注号码
- 汇总奖池并随时接受新的下注
- 开奖后逐条核对号码并计算奖励
- 依据命中情况分配奖池积分
该流程在参与人数增加时工作量显著上升。koishi-plugin-lottery-lizard 将下注、开奖与积分结算交由机器人执行,参与者可在群聊中完成完整的游戏流程。
工具定位
koishi-plugin-lottery-lizard 是一款基于 Koishi 框架的积分娱乐插件,主要能力如下:
| 能力 | 说明 |
|---|---|
| 大乐透下注 | 消耗积分选择号码下注,支持多次独立下注 |
| 奖池计算 | 依据参与人数动态调整奖池积分 |
| 自动开奖 | 生成开奖号码并按命中权重分配奖池 |
| 刮刮乐 | 消耗积分购买刮刮乐,即时返回中奖结果 |
| 期望管理 | 提供期望与方差信息,便于调整奖项权重 |
当前版本为 0.0.3,依赖 Koishi 4.18.8,并需搭配 monetary 与数据库服务使用。
安装
前置条件
- 已搭建并可正常运行的 Koishi 项目(
koishi-app) - 已启用 Koishi 的数据库服务(插件声明
inject: ['database', 'monetary'],下注与积分均依赖数据库) - 已安装并启用 monetary 插件(插件声明
inject: ['monetary'],积分读写依赖该服务)
方式一:通过插件市场安装(推荐)
- 启动 Koishi 项目,打开控制台(默认地址
http://localhost:5140)。 - 进入左侧「插件市场」。
- 在搜索框中输入
lottery-lizard。 - 找到插件后点击「添加」,Koishi 会自动完成依赖安装与配置写入。
方式二:通过 npm 安装
在 Koishi 项目根目录执行:
1 | npm install koishi-plugin-lottery-lizard |
随后在 koishi.yml 中手动添加配置:
1 | plugins: |
方式三:通过 yarn / pnpm 安装
若项目使用 yarn 或 pnpm,可执行:
1 | # yarn |
启用数据库
插件下注与积分读写均依赖数据库。若项目尚未配置,可在控制台「插件配置」中找到 database-sqlite 并启用:
1 | plugins: |
保存配置后重启 Koishi 项目,即可正常使用下注与开奖功能。
启用 monetary
插件声明了 inject: ['monetary'],积分读写依赖 monetary 服务。若尚未安装,可在插件市场搜索 monetary 添加并启用:
1 | plugins: |
currency 配置项需与 monetary 中定义的货币字段名称保持一致,默认值为 default。
验证安装
在任意已接入机器人的聊天窗口输入:
1 | 大乐透 |
若能返回大乐透规则文本,则说明安装成功。
配置
配置项
| 配置项 | 类型 | 默认值 | 取值范围 | 说明 |
|---|---|---|---|---|
currency |
string | default |
— | monetary 中的 currency 字段名称 |
prizes |
array | 见下文 | — | 刮刮乐奖项设置 |
costPerTicket |
number | 5 | ≥ 1 | 刮刮乐每张的价格 |
maxTicketCount |
number | 10 | ≥ 1 | 单次最多购买的刮刮乐数量 |
logExpectation |
boolean | false | — | 更新奖项后是否在控制台输出数学期望 |
奖项字段
prizes 为奖项数组,每一项包含以下字段:
| 字段 | 类型 | 说明 |
|---|---|---|
prob |
number | 中奖概率权重 |
reward |
number | 中奖金额 |
name |
string | 奖项名称 |
默认奖项
| 名称 | 权重 | 金额 |
|---|---|---|
| 天选之人 | 1 | 4999 |
| 至尊欧皇 | 5 | 1000 |
| 欧洲人 | 100 | 100 |
| 疯狂星期四 | 300 | 50 |
| 运气爆棚 | 800 | 30 |
| 狗屎运 | 1000 | 20 |
| 再来一张 | 80000 | 5 |
| 安慰奖 | 6000 | 2 |
配置示例
1 | plugins: |
开启 logExpectation 后,插件会在配置更新时向控制台输出单张数学期望、方差、各档命中率以及购买 maxTicketCount 张时的亏损率、平手率与盈利率。可据此调整奖项权重。
大乐透玩法
规则概述
- 每次下注消耗至少 20 积分,选择 1~18 中的 7 个数字下注
- 前 5 个数字为「前区」,不能重复;后 2 个数字为「后区」,可以重复
- 每人可多次下注,全部独立结算
- 开奖后按前区命中数量加权分配奖池
- 后区每猜中 1 个,固定奖励 5 积分
- 参与人数大于 3 人后,每增加 1 人,奖池额外增加 5 积分
开奖机制
前区命中数量对应权重如下:
| 前区命中数 | 权重 |
|---|---|
| 5 | 80 |
| 4 | 40 |
| 3 | 20 |
| 2 | 10 |
| 1 | 5 |
| 0 | 1 |
奖池按各玩家的权重占比分配,后区每命中一个额外固定奖励 5 积分,不影响奖池分配。
刮刮乐玩法
规则概述
- 消耗积分购买刮刮乐,系统自动返回中奖结果,可一次购买多张
- 单次购买数量上限由
maxTicketCount控制;由于方差较大,购买数量过多时盈利概率会显著上升 - 可参考控制台输出的期望与方差信息调整奖项权重设置
使用流程
大乐透
查看当前群聊大乐透下注情况
1 | 大乐透 |
返回当前下注次数、奖池积分与下注号码列表。若当前群聊暂无下注记录,则返回规则文本。
进行一次大乐透下注
1 | 大乐透.下注 25 |
若不输入下注积分数,则默认消耗 20 积分。下注后按提示输入号码:
1 | 1 2 3 4 5 1 1 |
号码范围为 1~18,前 5 个不能重复,后 2 个可以重复。号码的输入等待时长为 30 秒,超时视为取消下注。
若用户尚无积分记录,插件会赠送 20 积分作为初始资金并提示重新下注。
开奖
1 | 大乐透.开奖 |
机器人自动生成开奖号码,结算所有下注者的奖励,并清空当前群聊的下注记录。中奖与否均可获得奖池份额。
刮刮乐
购买刮刮乐
1 | 刮刮乐 5 |
默认购买 1 张,可选购买数量,购买后即时返回结果。若购买数量超过 maxTicketCount,插件会提示上限并以 maxTicketCount 计算。
技术实现
技术栈
| 技术 | 用途 |
|---|---|
| Koishi | 机器人框架 |
| TypeScript | 开发语言 |
| monetary | 积分服务 |
| 数据库服务 | 下注与积分持久化 |
数据表结构
插件通过 ctx.model.extend 扩展了两张表。
lotto 表存储大乐透下注记录:
| 字段 | 类型 | 说明 |
|---|---|---|
id |
string | 主键,取值为时间戳字符串 |
uid |
unsigned | 用户 ID |
channelId |
string | 群聊频道 ID |
numbers |
json | 下注号码(前区与后区) |
cost |
unsigned | 下注消耗的积分 |
monetary 表为 monetary 服务的数据表,插件通过 currency 定位货币字段。
核心设计
奖池计算
奖池由下注总额与额外奖励两部分构成:
1 | function calcPoolFromDB(bets: any[]) { |
基础奖池为全部下注金额之和;当参与人数超过 3 人时,每多 1 人额外增加 5 积分。
权重分配
开奖时按前区命中数查表得到权重,累加后按占比分配奖池:
1 | const weightTable = { 5: 80, 4: 40, 3: 20, 2: 10, 1: 5, 0: 1 } |
每位玩家的份额为 Math.ceil(pool * weight / totalWeight),再叠加后区奖励。
刮刮乐权重抽取
刮刮乐按权重随机抽取奖项:
1 | function drawPrize(prizes) { |
prob 为相对权重而非绝对概率,各奖项概率为 prob / 权重总和。
期望与方差输出
logExpectation 开启后,插件计算单张期望与方差,并通过卷积计算购买 maxTicketCount 张时的收益分布,输出亏损率、平手率与盈利率。该信息仅用于控制台显示,不参与实际开奖。
积分读写
积分通过 monetary 表读写,扣减前校验余额:
1 | const newValue = row.value + change |
若用户尚无积分记录且操作为非扣减,插件会先创建记录。
注意事项
1. 服务依赖
插件声明了 inject: ['database', 'monetary'],下注与积分读写均依赖数据库与 monetary 服务。若未启用二者,相关指令不可用。
2. 货币字段一致
currency 需与 monetary 中定义的货币字段名称保持一致。若不一致,插件将无法正确读写积分,并会创建独立的积分记录。
3. 初始资金
当用户尚无积分记录时,插件会赠送 20 积分作为初始资金。该行为在下注与刮刮乐指令中均会触发。
4. 号码输入
下注号码需为 7 个 1~18 之间的数字,前 5 个不可重复,后 2 个可重复,以空格分隔。号码输入等待时长为 30 秒,超时视为取消。
5. 数据清理
开奖后插件会清除当前群聊的全部下注记录。群聊与群聊之间的下注数据相互独立。
6. 方差风险
刮刮乐的方差较大,购买数量过多时盈利概率会显著上升。建议通过 logExpectation 查看收益分布后再调整奖项权重。
常见问题
Q1:安装后输入指令无响应?
依次检查以下项:
- 插件是否已在控制台启用
monetary服务是否已安装并启用database-sqlite等服务是否已启用- 机器人是否已成功连接至目标平台
- 指令是否完整输入(父指令
大乐透与子指令之间以点号分隔)
Q2:提示「你的 default 不足」?
说明当前积分不足以完成本次操作。可通过 monetary 相关的指令获取积分,或检查 currency 配置是否与实际使用的货币字段一致。
Q3:开奖后群聊下注记录消失了?
属于预期行为。开奖后插件会清除当前群聊的全部下注记录,以便开始新的对局。
Q4:刮刮乐实际中奖率与设置不符?
prob 为相对权重而非绝对概率,实际概率为 prob / 权重总和。可开启 logExpectation 查看各档实际命中率。
Q5:能否调整大乐透的奖池规则?
当前版本的大乐透权重表与奖池规则写死在源码中,不支持通过配置修改。刮刮乐的奖项、单价与数量上限可通过配置调整。
Q6:下注后未输入号码会怎样?
号码输入等待时长为 30 秒。超时后视为取消下注,本次下注不会扣除积分。
开发计划
- 支持自定义大乐透奖池规则
- 增加更多彩票玩法
- 支持跨群聊奖池
- 提供更丰富的中奖播报样式
获取工具
- npm 包:
koishi-plugin-lottery-lizard - GitHub 仓库:lizard0126/lottery-lizard
- 反馈建议:GitHub Issues
- 支持作者:请我喝可乐