- 新增 useGameBoardVm 数据层实施说明文档 - 添加 36字花核心玩法与前端规则摘要 - 创建游戏模块数据与界面分层第一阶段实施稿 - 定义四层架构:api/dto、store、view-model hooks、ui层 - 规范 PC 与 Mobile 共享业务逻辑的改造方案 - 明确各层职责边界和组件改造顺序
8.9 KiB
8.9 KiB
36字花核心玩法与前端规则摘要
1. 项目定位
36字花是一个单期开奖结果、单期号循环运行的实时开奖类游戏。
前端的核心界面是:
- 36 宫格下注盘
- 倒计时与当前期状态栏
- 筹码与确认下注区
- 开奖历史与走势信息
- 公告、规则、自动托管、充值提现等外围模块
产品运行原则:
- 全平台共享同一局数据
PC与Mobile只分界面,不分玩法、不分对局- 前端必须以服务端状态为准,不能靠本地时间自行判断开奖或封盘
2. 核心玩法
2.1 基本盘面
- 游戏共有 36 个号码格子
- 每个格子代表一个“字花编号”
- 编号范围为 1-36
- 当前前端盘面布局为 6 x 6
相关代码与约束:
- src/features/game/shared/constants.ts
GAME_GRID_ROWS = 6GAME_GRID_COLUMNS = 6GAME_TOTAL_CELLS = 36
2.2 开奖规则
- 每一期只会开出 1 个中奖号码
- 开奖号码属于 1-36 中的一个
- 用户只要下注号码集合中包含该号码,即视为中奖
接口口径见:
- docs/36字花-移动端接口设计草案.md
POST /api/game/placeBet
文档原意:
- 玩家提交的是“号码集合 + 单注金额”
- 系统按“单注金额 × 号码数量”计算本笔总扣款
- 开奖后只出一个号码
- 若该号码命中玩家所选集合,则该笔下注中奖
3. 下注模型
3.1 单注结构
一笔下注至少包含:
period_no:下注目标期号numbers:本次下注号码集合single_bet_amount:单个号码的下注金额
说明:
numbers是一个号码集合,而不是单个号码- 多选号码时,总扣款 =
single_bet_amount × numbers数量 - 重复号码应去重
3.2 前端当前数据模型
当前前端 store 中的单笔选择数据为:
cellIdchipIdamountplacedAtsource
定义见:
- src/features/game/shared/types.ts
BetSelection
当前本地 mock 与 store 落地方式是:
- 每点击一个格子,会追加一条
selection - 每条
selection对应一个格子和一个筹码金额
这与接口文档中的“号码集合提交”并不完全一致。
因此当前前端可以先采用如下理解:
- UI 交互阶段:按“逐格选择”记录本地状态
- 提交到后端阶段:再把本地多个格子聚合成
numbers
这是后续 confirm bet 需要承担的转换逻辑。
4. 回合状态机
4.1 当前状态枚举
当前项目中定义的回合阶段为:
waitingbettinglockedrevealingsettled
定义见:
接口文档中的状态口径包括:
bettinglockedsettlingfinishedvoid
说明:
- 当前前端内部状态和接口文档状态还未完全统一
- 第一阶段前端可继续沿用内部状态机
- 后续真实联调时,要补一层接口状态 -> 前端状态的映射
4.2 各阶段前端规则
BETTING
- 允许选格子
- 允许切换筹码
- 允许清除当前选择
- 允许重复上一注
- 允许确认下注
- 允许开启自动托管
LOCKED
- 已封盘
- 前端必须立即停止下注交互
- 不应等待后端返回后才禁用点击
REVEALING / SETTLING
- 等待开奖与派彩
- 展示开奖结果、跑马灯、中奖态
SETTLED / FINISHED
- 本期结束
- 准备进入下一轮
- 历史、走势、余额等应刷新
VOID
- 本期作废
- 需要退款待开奖本金
- 前端要清理本期下注态并正确提示
5. 封盘与倒计时规则
5.1 核心原则
- 前端必须以服务端返回的时间和阶段为准
- 到达封盘时间点时,前端应立即锁盘
- 即使网络延迟,也不能继续允许下注交互
这点在需求文档中是明确要求:
5.2 当前前端倒计时模型
当前前端使用:
round.bettingClosesAtround.revealingAtround.settledAt
并通过:
- src/features/game/shared/selectors.ts
getRoundCountdownMs(round)
来计算当前倒计时毫秒数。
规则如下:
waiting / betting:倒计时到bettingClosesAtlocked / revealing:倒计时到revealingAt- 其余:倒计时到
settledAt
5.3 Mock 数据口径
当前 mock 数据中:
- 开始后约 18 秒封盘
- 约 24 秒开奖
- 约 30 秒结算
来源:
这只是前端演示节奏,不代表最终真实服务端配置。
6. 赔率、金额与筹码规则
6.1 当前赔率
当前 mock 中每个格子赔率固定为:
36
来源:
- src/features/game/shared/mock-data.ts
createGameCells()
6.2 当前默认筹码
当前默认筹码面额为:
102550100200500
来源:
- src/features/game/shared/constants.ts
DEFAULT_GAME_CHIP_AMOUNTS
6.3 下注限制
从接口文档与基线需求中可得出以下前端规则:
- 单次下注号码数量不得超过
pick_max_number_count - 单号码下注金额不得超过
single_number_max_bet - 总下注额不得超过余额
- 封盘后不能继续下注
文档来源:
7. 中奖、历史与走势
7.1 历史记录
每期开奖后应产生一条历史记录,至少包括:
roundIdwinningCellIdsettledAtpayoutMultipliertotalPoolAmount
定义见:
- src/features/game/shared/types.ts
HistoryEntry
7.2 走势
前端会基于历史数据派生走势信息,包括:
currentStreakhitCountmissCountdirectionlastHitRoundId
派生逻辑见:
- src/features/game/shared/selectors.ts
deriveTrendEntries(history)
说明:
- 走势属于纯派生展示数据
- 不应由 UI 组件自己重复计算
8. 公告、维护与运行开关
8.1 运行开关
接口文档中存在:
runtime_enabled
含义:
true:游戏正常运行false:后台维护中,禁止下注
规则:
- 维护中不允许新下注
- 当前已开盘的一局仍可正常开奖和派彩
- 前端应禁用下注入口并提示维护状态
8.2 公告
公告是前端大厅的一部分,但不属于主玩法。
当前前端已存在公告模型:
AnnouncementStateAnnouncementItem
它们属于会话层状态,不应混入下注与回合逻辑。
9. 自动托管
接口文档中已定义自动托管能力:
POST /api/game/autoSpin
入参包括:
actionperiod_nonumberssingle_bet_amountrounds
说明:
- 自动托管属于建立在主玩法之上的扩展能力
- 它依赖同一套选号与下注规则
- 当前前端可以先保留 UI 壳层,不需要在主玩法没走通前抢先落业务
10. 前端当前最应该优先走通的主玩法链路
基于上述规则,当前前端最核心、最应该优先走通的是:
- 状态栏拿到当前期状态与倒计时
- 控制栏拿到当前筹码与总下注额
- 选号盘点击格子后写入本地下注选择
- 总下注额、选中数量、选号高亮联动刷新
- 后续再补确认下注请求与开奖结果回写
这也是为什么当前下一步应优先实现:
useGameBoardVm
而不是优先改 mobile 或外围弹窗。
11. 总结
36字花这个项目的核心,不是“36 张图摆出来”,而是下面这条实时对局链路:
- 同一局
- 同一倒计时
- 同一开奖结果
- 36 格可选号码
- 用户用统一筹码模型下注
- 封盘、开奖、派奖按服务端状态推进
前端实现时必须坚持两点:
-
玩法规则统一
- PC 和 Mobile 只能换壳,不能换规则
-
服务端状态优先
- 前端可以先做本地交互反馈
- 但回合状态、封盘、开奖、派彩都必须最终以服务端为准