二七王文档:记录二次全量复核结论 + §5.4.4 修复同步
- compliance/01:新增二次对抗性复核结论(服务端全部符合 design.md); §5.4 标记全部完成、§5.4.4 已修;修正过时的 §10.1 数组下标描述 - packet_protocol.md:playproc 补 shuai_demand 字段说明 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -17,6 +17,9 @@
|
||||
|
||||
> 本轮已按 design.md 修正的项(均已用 Node 脚本对 design 判定表逐格验证,见"验证"列)。下方"结论摘要"与各节详评仍保留**原始不一致**描述以留痕;本节记录当前状态。
|
||||
|
||||
> **二次全量复核结论**:对整改后代码做了一次独立对抗性复核(§7/§8 算子算奖、§5 出牌甩牌、§4 开局投降暗牌阶段机、§2/§3/§9/§10 编码查牌房间,逐条比对 + Node 实测)。结果:**服务端全部符合 design.md**,且未发现整改引入的符号/下标/边界错、无 step4 死代码残留、投降 36 张快照与 X×N 算奖均正确。
|
||||
> - 复核时发现的唯一未落地项 **§5.4.4 强制跟牌分量拆解已于本轮修复**:合法甩牌在 `can_playcard` 记录分量需求 `shuai_demand`(拖拉机长度/对子/单张),存入 `playproc`;跟牌时 `do_playcard` 调 `arith.flush_follow_ok` 在"同花色凑张数、主牌最大化"之上追加"拖拉机→对子→单张"的强制分量匹配(能凑同长主拖必凑、能凑主对必凑,不得拆散去垫)。已用 Node 正反面/边界用例验证。
|
||||
|
||||
| 项 | 位置 | 整改内容 | 验证 |
|
||||
| --- | --- | --- | --- |
|
||||
| D1 崩溃 | `class.arith.js` `can_followcard` | 用 `get_pairlist`+`get_tuolaji_list(_followcards)` 校验拖拉机牌型,消除未定义 `tuolaji_list` | 语法通过 |
|
||||
@@ -31,7 +34,7 @@
|
||||
| §4.2 | `mod.jiaofen` | 增加叫分上限 `call<=70` | — |
|
||||
| §4.4 投降 | `mod.touxiang` + `do_burycard` + `get_deskinfo` | 投降仅 70 分、在**选主阶段 step2** 与选主互斥、不选主不埋牌;结算基础 1、庄输 1 子/闲;算奖用庄家 **36 张**(发牌+暗牌,无主花色→无连对链);埋牌后 step 直接进 5、删除已废弃的投降 step4 与重连 Surrender 视图 | — |
|
||||
| §10.1 | `get_asetcount`/`get_needroomcard` | 局数 6/12;房主扣卡 2/4 | — |
|
||||
| §5.4 甩牌 | `arith`(新增 `trump_rank`/`decompose_trump`/`opp_can_beat_flush`)+ `can_playcard` + `do_playcard` + `mod.chupai` | 副牌绝对禁甩;最大性改为**按对手全部主牌**逐分量判定;甩错惩罚(收回、只打最小一张、下发 `shuaicuo`) | ✅ 分解/最大性/各路径用例 |
|
||||
| §5.4 甩牌 | `arith`(新增 `trump_rank`/`decompose_trump`/`opp_can_beat_flush`/`flush_follow_ok`/`remove_pairs`)+ `can_playcard` + `do_playcard` + `mod.chupai` | 副牌绝对禁甩;最大性改为**按对手全部主牌**逐分量判定;甩错惩罚(收回、只打最小一张、下发 `shuaicuo`);**§5.4.4 强制跟牌分量拆解**(拖拉机→对子→单张优先级,`shuai_demand`+`flush_follow_ok`) | ✅ 分解/最大性/各路径/跟牌分量用例 |
|
||||
| roomtype | `class.config.js`(新)+ `export`/`paiju` | 数组下标改为**位串**(`"01011"`),`class.config.js` 唯一解析(SSOT) | ✅ parse/扣卡/局数用例 |
|
||||
| §4 暗牌亮牌 | `shangzhuang` + `get_deskinfo` | 70 分坐庄把 8 张暗牌下发给所有玩家 + `ancard3s=1`(供摸牌前亮 3 秒);修正**非 70 分暗牌泄露给闲家**(现暗牌只发庄家,符合 §4"只有庄家可见");重连的暗牌一律仅庄家可见 | — |
|
||||
| §8.2 亮牌 | `get_liangpai`(新)+ `mod.maipai` + `get_deskinfo` | 庄家埋牌后 28 张按阈值(固定主≥10/王≥3/7≥6/2≥6)统计,出牌开始向闲家亮(只亮数量/结构);可查牌模式才下发 | ✅ 阈值/统计用例 |
|
||||
@@ -39,7 +42,7 @@
|
||||
|
||||
**尚未整改(多需与客户端/协议协同,或为较大的独立子系统)**:
|
||||
|
||||
- 🟩 **§5.4 甩牌(已改大部)**:副牌绝对禁甩、最大性按对手全部主牌逐分量判定、甩错惩罚均已实现并验证。**剩余**:§5.4.4 跟甩牌时"拖拉机→对子→单张"的**分量优先级**未强约束——现状是跟牌方必须用主牌按张数跟、且合法甩牌恒不可反超(结果正确),但不强制它优先用主对/主拖拉机去对位。因该细节不改变本轮胜负归属,列为后续精化项。
|
||||
- ✅ **§5.4 甩牌(已全部完成)**:副牌绝对禁甩、最大性按对手全部主牌逐分量判定、甩错惩罚、以及 §5.4.4 强制跟牌分量拆解(`flush_follow_ok`:拖拉机→对子→单张优先级)均已实现并用 Node 验证。
|
||||
- 🟩 **§9 查牌 / §8.2 亮牌(服务端已完成)**:亮牌 `get_liangpai`(庄家埋牌后 28 张按阈值统计)在 `maipai`/重连下发给闲家;报无主的座位统计(`info`/`baozhu`/`PushCards.seatlist`)与亮牌均按查牌位 `cfg.nocheck` 门控(不查牌一律不下发);新增 `mingpai` RPC(可查牌 + 已报无主时查看他家全部主牌)。剩客户端展示(面板/明牌按钮)。
|
||||
- 🟩 **§4.4 70 分暗牌亮 3 秒(服务端已就绪)**:`shangzhuang` 对 70 分坐庄把 8 张暗牌下发给所有玩家并带 `ancard3s=1`,供客户端在庄家摸暗牌前亮 3 秒;顺带修正了**非 70 分把暗牌泄露给闲家**的问题(现非 70 分暗牌只发庄家,符合 §4"只有庄家可见")。剩下的 3 秒动画由客户端完成。
|
||||
- 🟧 **§11 闲家 3 提示(踩/没分/有分)**:交互展示,需客户端配合。
|
||||
@@ -149,7 +152,7 @@
|
||||
|
||||
### §5.4 甩牌 — 🟥 原合法性 / 禁令 / 跟牌 / 惩罚多处不符(🟩 第 1/2/4 点已整改,见「整改进度」)
|
||||
|
||||
> **整改状态**:下述第 1(副牌禁甩)、第 2(最大性按全手牌判定)、第 4(甩错惩罚)已实现并验证;第 3(强制跟牌分量优先级)为剩余精化项。以下保留原始不一致描述留痕。
|
||||
> **整改状态**:下述第 1(副牌禁甩)、第 2(最大性按全手牌判定)、第 3(强制跟牌分量优先级,`flush_follow_ok`)、第 4(甩错惩罚)**均已实现并验证**。以下保留原始不一致描述留痕。
|
||||
|
||||
1. 🟥 **副牌禁甩未落实**:设计 §5.4.1「所有副牌完全禁止甩牌,无论外面是否剩余该花色副牌」。代码 `can_playcard` 对副牌甩牌只要求「其他两家没有主牌 **且** 没有该副花色(`other_noflower`)」即**放行**(约 415-419、427-438 行),等于「对手缺门时允许甩副牌」,与绝对禁令冲突。
|
||||
2. 🟥 **甩牌合法性判定模型不符**:设计 §5.4.2 要求服务端**按全部手牌**判断「对手是否持有能压过甩牌任一分量的更大主牌 / 主对 / 更长主拖拉机」。代码改用出牌过程累积的 `seatlist[i][flower-1][0/1]`、`[4]` 等**报副标志**(`other_noflower`/`other_noflowerpair`),语义是「对手是否已被记录为该花色 / 主牌 / 对子出空」,既非「按全部手牌」也非「更大」而是「有没有」,与设计判定完全不同。
|
||||
@@ -255,10 +258,12 @@
|
||||
|
||||
## §10 房间设置选项 — 🟥
|
||||
|
||||
### §10.1 扣卡方式 / 局数 — 🟥
|
||||
### §10.1 扣卡方式 / 局数 — ✅ 已整改(下述为原始不一致留痕)
|
||||
|
||||
- 🟥 **局数不符**:`export.get_asetcount` 返回 `roomtype[0]==1→2`、`==2→4`。设计 §10.1 为 **6 局 / 12 局**。(疑为占位 / 测试值,与 `do_playcard` 中被注释的 `round==2` 测试残留同源。)
|
||||
- 🟥 **房主扣卡数不符**:`get_needroomcard` 房主档(`roomtype[2]==1`)返回 1/2;设计房主扣卡为 6 局 2 张 / 12 局 4 张。AA 档(`roomtype[2]==2`)返回 1/2,与设计 AA「每人 1 张 / 2 张」一致。
|
||||
> **现状(已改)**:`get_asetcount` 按位串返回 6/12;`get_needroomcard` 房主 6局2张/12局4张、AA 6局1张/12局2张,均符合 §10.1。以下为原始(数组下标版)不一致记录。
|
||||
|
||||
- 🟥(原始)**局数不符**:旧 `export.get_asetcount` 返回 `roomtype[0]==1→2`、`==2→4`。设计 §10.1 为 **6 局 / 12 局**。
|
||||
- 🟥(原始)**房主扣卡数不符**:旧 `get_needroomcard` 房主档返回 1/2;设计房主扣卡为 6 局 2 张 / 12 局 4 张。
|
||||
|
||||
### §10.2 查牌模式 — 🟥 无开关(见 §9)
|
||||
|
||||
|
||||
@@ -396,7 +396,7 @@
|
||||
| bottomcards | 数组 | 埋的牌,只有庄家有此属性 |
|
||||
| grade | 整数 | 当前的捡分分数 |
|
||||
| gradecards | 数组 | 当前的捡分分牌,只有闲家有此属性 |
|
||||
| playproc | json | 当前出牌情况 `o_paiju.playproc`:`round` 第几轮、`start` 本轮首出位置、`currseat` 当前出牌位置、`startcount` 首出张数、`startflower` 首出花色、`starttype` 首出牌型、`maxseat` 本轮最大者位置、`maxcard` 最大牌编码、`cards` 本轮三家各自出的牌(数组下标=位置序号) |
|
||||
| playproc | json | 当前出牌情况 `o_paiju.playproc`:`round` 第几轮、`start` 本轮首出位置、`currseat` 当前出牌位置、`startcount` 首出张数、`startflower` 首出花色、`starttype` 首出牌型、`maxseat` 本轮最大者位置、`maxcard` 最大牌编码、`cards` 本轮三家各自出的牌(数组下标=位置序号)、`shuai_demand` 首家甩牌的分量需求 `{tractors:[连对数...],pairs,singles}`(非甩牌为 null,供跟牌逐分量强制匹配,design §5.4.4)|
|
||||
| seatlist | 数组 | 三家座位牌况,元素结构同上文 chupai 包的 `info`(每个玩家一个 5 元素数组:4 个花色的 `[无该花色,无对]` + 报副 `[剩余主牌数,剩余主对数]`)。**仅可查牌模式下有此属性**(design §9)|
|
||||
| liangpai | json | 庄家亮牌信息,结构同 maipai 包的 `liangpai`;**仅可查牌模式、且请求者为闲家、且庄家达标时有**(供闲家重连后仍能看到亮牌,design §8.2)|
|
||||
| pushlist | 数组 | 出牌历史 `[[[], [], []], [[], [], []], ...]`,外层下标=轮次,内层 3 个数组按位置序号存该轮各家出的牌id(已按大小排序) |
|
||||
|
||||
Reference in New Issue
Block a user