8.9 KiB
大富翁 · 摇色子 — 项目文档
本文描述业务玩法与服务端抽奖/结算机制,便于产品、运营与二次开发对齐实现。接口路径、鉴权与联调细节见根目录 API对接文档.md。
1. 项目概述
- 形态:平台玩家使用「平台币」参与摇五颗标准六面骰(点数各 1–6),结果对应棋盘/奖励配置;后台可配置档位权重、奖池、杀分策略与展示文案(含中英文)。
- 服务端:PHP Webman(
server/),玩家与平台接口在app/api;骰子业务模型在app/dice。 - 管理端:前端工程
saiadmin-artd/(与 SaiAdmin 插件体系配套)。
2. 核心概念
| 概念 | 说明 |
|---|---|
平台币 coin |
玩家钱包余额;付费开局、购买套餐、中奖结算均围绕该字段。 |
注数 ante |
倍数因子,须存在于表 dice_ante_config 的 mult 中;接口 /api/game/anteConfig 返回可选注数。 |
| 单注费用 | 付费抽奖时,开局前扣除 ante × 1 平台币(代码常量 UNIT_COST = 1,即「单注 1 币」口径)。 |
方向 direction |
开局参数:0 与 1 对应两套奖励数据(顺时针/逆时针或「无 / 中奖」分支,由前端与配置表共同约定);服务端在 档位确定后,按当前方向从 DiceReward 缓存结构中取该档位下的条目再按权重抽取。 |
| 档位 T1–T5 | 中奖层级;先抽档位,再在该档位 + 当前方向下按 weight 抽一条奖励配置。 |
grid_number(5–30) |
与「五颗骰子点数之和」一致:最小 5(全 1),最大 30(全 6);用于关联奖励行与后续生成 roll_array。 |
real_ev |
奖励配置中的期望调节项;普通中奖结算为 real_ev × ante(付费局在开局已扣 ante×1,净效果依 real_ev 而定)。 |
3. 玩法流程(玩家视角)
-
登录 / 进游戏
平台侧通过/api/v1/getGameUrl或玩家侧/api/user/Login换取 token,打开前端页面。 -
(可选)购买「抽奖券」套餐
POST /api/game/buyLotteryTickets,count仅支持1、5、10:- 1:1 币 → 1 次付费计数 + 0 次赠送
- 5:5 币 → 5 次付费 + 1 次赠送(共 6 次计入总次数)
- 10:10 币 → 10 次付费 + 3 次赠送(共 13 次)
会更新玩家身上的
total_ticket_count/paid_ticket_count/free_ticket_count,并记钱包与券流水。 -
开局抽奖
POST /api/game/playStart,需传direction(0 或 1) 与ante(正整数,且须在底注配置中)。 -
付费 vs 免费
- 免费抽奖:当
free_ticket_count > 0时,本局视为免费类型:不扣ante×1,但会消耗 1 次free_ticket_count。 - 付费抽奖:不依赖「券张数是否大于 0」;只要非免费局,开局前扣
ante × 1。
重要:当前实现已不再用「抽奖券张数」作为能否开局的条件;
buyLotteryTickets更新的是统计与赠送次数,真正开局仍看余额、注数、免费次数等规则(见下节)。 - 免费抽奖:当
-
免费注数锁定
若上一局因命中 T5 赠送了免费次数,服务端会缓存「免费局须与触发时相同的ante」,不一致则拒绝并提示修改注数。
4. 抽奖与结算机制(服务端逻辑)
以下对应 PlayStartLogic 与 LotteryService,便于理解「先抽什么、再算什么钱」。
4.1 前置校验
- 用户存在;
ante合法。 - 最低余额:
coin ≥ abs(min_real_ev) × ante(min_real_ev来自全表DiceRewardConfig缓存),防止极端负 EV 下余额不足以覆盖风险口径。 - 付费局:
coin ≥ ante × 1。
4.2 使用哪套「档位权重」:默认奖池 vs 杀分奖池
配置表 dice_lottery_pool_config 至少要有 name = default;可选 name = killScore。
default彩金池维护累计盈利字段profit_amount(见 4.5)。- 记:
safety_line= 安全线,kill_enabled= 是否开启杀分。
是否按「奖池档位权重」抽档位(usePoolWeights):
| 情形 | 档位权重来源 |
|---|---|
| 免费局 | 使用 killScore 奖池的 T1–T5 权重;若无 killScore 则退回 default。 |
付费局 且 杀分开启 且 profit_amount ≥ safety_line 且 存在 killScore |
使用 killScore 的档位权重(杀分模式)。 |
| 其他付费局 | 使用 玩家身上的 t1_weight~t5_weight(DicePlayer 字段,与 LotteryService::drawTierByPlayerWeights 一致)。 |
档位抽出 T1–T5 后,从 DiceReward 缓存中取出 [该档位][direction] 下的所有奖励行,再按行 weight 做加权随机(仅 weight > 0 参与;全为 0 会重试档位,最多约 10 次)。
4.3 杀分模式下的特殊处理
当使用 killScore / 免费局 等与杀分一致的权重路径时:
- 在奖励抽取阶段会 排除
grid_number为 5 和 30 的配置(这两点数和只能对应「全 1」「全 6」豹子,无法做成非豹子展示)。 - 不会触发豹子大奖(见 4.4):若摇到豹子点数组,只生成 非豹子 的五骰组合,不发放豹子附加奖金。
4.4 普通奖与「豹子 / BIGWIN」
-
若本次抽中的
grid_number不是「豹子集合」{5,10,15,20,25,30}:按点数和生成 5 个 1–6 的骰子(和为grid_number),普通奖金 =real_ev × ante(付费局已预先扣除ante×1)。 -
若点数和落在豹子集合:
grid_number为 5 或 30:若非杀分路径,必定按豹子结算(五颗相同点数)。- 10 / 15 / 20 / 25:读取
DiceRewardConfig中tier = BIGWIN且对应该grid_number的配置,用其weight(0–10000,10000=100%) 随机决定是否视为真豹子;否则生成非豹子但点数和不变的骰子组合。 - 真豹子时:奖金按
big_win_real_ev × ante发放(big_win_real_ev来自 BIGWIN 配置;若未配则用代码兜底常量);并不计入当次普通reward_win那条配置(与「中豹子不走普通奖」逻辑一致,详见代码注释)。
杀分路径下:不触发豹子奖,仅展示非豹子组合。
4.5 T5「再来一次」
若命中奖励属于 T5 档位(且未走「仅豹子清掉普通奖」的特殊分支):在事务内为玩家 free_ticket_count + 1,并写入券流水备注;同时写入 Redis:下一局免费抽奖必须使用本局相同 ante。
4.6 彩金池盈利累计
在 default 那条池子上更新 profit_amount:
- 付费局:本局贡献
+= (本局总中奖 win_coin) - (本局付费 paid_amount),其中paid_amount = ante × 1。 - 免费局:
+= win_coin(无票价成本,paid_amount = 0)。
该累计值与 safety_line、 kill_enabled 共同决定下一局付费是否进入 killScore 档位权重(见 4.2)。
注意:仓库中部分数据库迁移脚本对
profit_amount的注释可能仍沿用旧口径。当前行为应以PlayStartLogic中对profit_amount的实际累加逻辑为准。
5. 数据与配置要点(实现侧)
DiceReward:按档位、方向组织好的多语言/展示与grid_number、weight、real_ev等,供开局加权抽取。DiceRewardConfig:含 BIGWIN 档及普通档;getCachedMinRealEv()等用于全局限定。dice_lottery_pool_config:default/killScore的 T1–T5 权重及杀分相关开关、安全线、累计盈利。- 对局表
DicePlayRecord:记录lottery_config_id、lottery_type(付费/免费)、ante、paid_amount、roll_array、reward_tier、各类中奖拆分字段等,供后台与平台对账。
6. 接口与文档索引
| 文档 | 内容 |
|---|---|
API对接文档.md |
平台 /api/v1/*(auth-token)、玩家 /api/*(token)、统一返回码、联调建议。 |
server/docs/ |
性能、权重测试、出点分析等专项说明(按需阅读)。 |
与玩法直接相关的玩家接口示例:
GET /api/game/config— 前端文案与分组配置GET /api/game/anteConfig— 可选注数GET /api/game/lotteryPool— 彩金池展示列表(不含 BIGWIN 档)POST /api/game/buyLotteryTickets— 购买套餐(更新次数统计)POST /api/game/playStart— 开局一局(direction、ante)
7. 修订说明
- 本文档依据
server/app/api/logic/PlayStartLogic.php、GameLogic.php、LotteryService.php及GameController当前实现整理;若业务规则变更,请以代码与数据库迁移为准并同步更新本节与API对接文档.md。