# 色子点数（5–30）抽中概率分析

## 一、当前流程（为何 5 和 30 容易出、部分点数可能摇不到）

点数 `rollNumber`（5–30）由**两步**决定，而不是在 5–30 里直接按权重抽一次：

1. **先抽档位**  
   按池子/玩家权重抽 T1–T5 之一。

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_number（5–30），是否存在至少一行 **s_end_index = 某个在 T1–T5 里出现过的 id**，且该行 weight > 0。  
  （“在 T1–T5 里出现过的 id” = 作为某条 T1–T5 配置的主键 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 的权重和是否明显高于 6–29，导致在该路径组内一抽就经常是 5 或 30。

## 五、可选：打开调试日志看“本局路径组里有哪些点数”

在 `PlayStartLogic` 里，在 `$startRecord = drawRewardByWeight(...)` 之后可加一段**仅调试时启用**的日志，例如：

- 打出：`chosenId`、`direction`、本局路径组里出现的 **grid_number 列表**及每个 grid_number 的**权重和**（或条数）。  
这样可以看到：每次抽奖时“实际参与抽奖的点数集合”是哪些，5、30 在该组里的权重是否偏大，以及哪些点数从未出现在日志里（即被跳过）。

---

**结论**：  
- 5 和 30 摇到的概率大，是因为在“当前 chosenId 对应的路径组”里，它们权重高或出现次数多。  
- 某些点数摇不到，是因为它们没有出现在任何“本局会用到”的路径组里，或只出现在极少被选中的路径组里。  
要平衡概率，需要从**路径数据**入手：保证每个点数 5–30 至少出现在若干路径组中且 weight>0，并调低 5、30 在路径组内的权重或条数占比。
