This commit is contained in:
2026-03-16 09:10:39 +08:00
parent ed46f18415
commit 72b43759f1
5 changed files with 379 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
# 色子点数530抽中概率分析
## 一、当前流程(为何 5 和 30 容易出、部分点数可能摇不到)
点数 `rollNumber`530由**两步**决定,而不是在 530 里直接按权重抽一次:
1. **先抽档位**
按池子/玩家权重抽 T1T5 之一。
2. **再在该档位内按权重抽一条“奖励配置”**
`$chosen = drawRewardByWeight(tierRewards)`,得到一条配置,记其主键为 `chosenId`
3. **按 chosenId 取“路径候选”**
- 顺时针:`startCandidates = getCachedBySEndIndex(chosenId)` → 所有 **s_end_index = chosenId** 的配置。
- 逆时针:`startCandidates = getCachedByNEndIndex(chosenId)` → 所有 **n_end_index = chosenId** 的配置。
4. **在路径候选中再按权重抽一条**
`$startRecord = drawRewardByWeight(startCandidates)`,最终 **rollNumber = $startRecord['grid_number']**
因此:
- **本局能出现哪些点数,完全由“当前 chosenId 对应的路径组”决定。**
- 只有**在 startCandidates 里出现的 grid_number** 才会被摇到;**不在该组里的点数本局根本不会参与抽取**,相当于被“跳过”。
## 二、为何 5 和 30 摇到的概率会很大
可能原因:
1. **路径数据里 5、30 占比高**
对很多 `chosenId`,其 `s_end_index=chosenId`(或 n_end_index的配置里grid_number=5 和 30 的条数多、或 weight 设得大,其它点数少/权重小,所以在这组里一抽就经常是 5 或 30。
2. **被抽中的 chosenId 偏集中在“含 5、30 的路径组”**
档位内按权重抽到的 `$chosen` 的 id如果经常落在某几类 id 上,而这些 id 对应的路径组里又以 5、30 为主,整体就会表现为 5、30 出现很多。
3. **5、30 出现在很多路径组里**
若 5、30 对应的配置的 `s_end_index`/`n_end_index` 覆盖了很多不同的 id即出现在很多“路径组”里而其它点数只出现在少数几个 id 的路径组里,那么 5、30 被抽到的机会自然更多。
## 三、为何有些点数“摇不到、像被跳过”
- 某点数 **grid_number = G** 本局能出,**仅当**
当前 `chosenId` 对应的路径组里,**存在至少一条配置的 grid_number = G**(且 weight>0 会参与权重抽)。
- 若在**所有** `s_end_index = 某 id`(或 n_end_index的路径组里**都没有** grid_number=12 的配置,那么 12 就**永远不会**被摇到,即被“跳过”。
- 若 12 只出现在“很少被选中的 chosenId”对应的路径组里例如这些 id 在档位内权重很低),那 12 就会**很少**出现。
所以:**不是代码故意跳过某些点数,而是这些点数在当前数据下,没有进入“本局实际参与抽奖的那组路径”里。**
5、30 摇得多 = 它们在这组路径里权重大或出现次数多;某些点数摇不到 = 它们没进这组路径或权重为 0。
## 四、建议的数据检查(在库里直接查)
`dice_reward_config` 表里可以做两类检查:
**1每个点数是否至少能出现在某个路径组里避免永远摇不到**
- 顺时针:对每个 grid_number530是否存在至少一行 **s_end_index = 某个在 T1T5 里出现过的 id**,且该行 weight > 0。
(“在 T1T5 里出现过的 id” = 作为某条 T1T5 配置的主键 id。
- 逆时针:同上,把 `s_end_index` 换成 `n_end_index`
若某点数在顺时针(或逆时针)下没有任何一条这样的行,则该点数在该方向下**永远不会**被摇到。
**2各点数在“路径组内”的权重是否过于悬殊**
- 对常见的 chosenId例如在 T1 里权重高的几条配置的 id
`SELECT grid_number, SUM(weight) FROM dice_reward_config WHERE s_end_index = ? AND tier IN ('T1','T2',...) GROUP BY grid_number`
看 5、30 的权重和是否明显高于 629导致在该路径组内一抽就经常是 5 或 30。
## 五、可选:打开调试日志看“本局路径组里有哪些点数”
`PlayStartLogic` 里,在 `$startRecord = drawRewardByWeight(...)` 之后可加一段**仅调试时启用**的日志,例如:
- 打出:`chosenId``direction`、本局路径组里出现的 **grid_number 列表**及每个 grid_number 的**权重和**(或条数)。
这样可以看到每次抽奖时“实际参与抽奖的点数集合”是哪些5、30 在该组里的权重是否偏大,以及哪些点数从未出现在日志里(即被跳过)。
---
**结论**
- 5 和 30 摇到的概率大,是因为在“当前 chosenId 对应的路径组”里,它们权重高或出现次数多。
- 某些点数摇不到,是因为它们没有出现在任何“本局会用到”的路径组里,或只出现在极少被选中的路径组里。
要平衡概率,需要从**路径数据**入手:保证每个点数 530 至少出现在若干路径组中且 weight>0并调低 5、30 在路径组内的权重或条数占比。