Commit Graph
11 Commits
Author SHA1 Message Date
joywayerandClaude Opus 5 b924b6e864 二七王:第八轮核对(流程/牌型/玩法/算分)+ 新增阶段机迁移矩阵用例
规则方复述「开局庄家先叫分、不允许不叫分;第一局无庄家时默认座位0开始叫分」,
据此按四个维度重新取证,未发现不一致。

新增此前从未做过的取证:**阶段机迁移矩阵**。前几轮每个 handler 只测了 1~2 条
代表性失败路径,从没系统验证过「某个请求在别的阶段会不会被误放行、会不会静默
丢弃」。本轮把 8 个 RPC × 5 个阶段做成 40 格矩阵逐格驱动,全部符合:每个 RPC
只在应允阶段受理,其余一律回 STEP 失败包,无静默丢弃。

叫分起始者规则逐条取证,与规则方复述一致:
- 第一局 firstseat=0、待叫者=0
- 之后每局起始 = 暂定庄家:连打 6 局逐局比对「上局 banker + result」
- 庄赢连庄:随机对局几乎打不出 result=0,用「叫70分 + 首家出最大牌」专门构造
- 庄输/投降顺延下家
- 首家不允许「不叫」:第一局与其后每局(含连庄局)发 call=0 一律回 RULE,
  且叫分过程不变、仍轮到他自己

固化为 test/test_flow.js(7 项聚合断言,0.3s)。断言里带 cells===40,防止驱动
失败导致整行「跳过」而假绿。变异检验:去掉 chupai/maipai 的阶段校验、把 jiaofen
的阶段校验改成静默丢弃 —— 三条全部转红。

全套单测 540 → 547 项全绿。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 14:59:46 +08:00
joywayerandClaude Opus 5 b5d9eece5d 二七王:第七轮核对(反方向 代码→design)+ 新增下发面泄露审计
前六轮都是「design → 代码」方向。本轮反过来:从代码出发,把每个规则决策与
常量拉出来追问 design 有无明文依据。没有发现与 design 冲突的行为,但列出 6 项
「design 未明文规定、由代码自行决定」的项(倒计时秒数、§5.4.4 降级阶梯是否
最长优先、甩牌分解的最大化合并约定、同级副7对不成连对、call 入参宽松而 cards
严格、get_chongguan 的 <28 隐式兜底),已写进 compliance 待规则设计者拍板。

同时补上一块此前完全没有测试的红线:**下发面按可见性下发**。design §4 暗牌
只有庄家可见、§9 查牌模式、§11 结束亮底牌,以及 server 红线「发全 ≠ 发多」,
此前各处门控只有逐条手工核对,从未系统验证「有没有哪个包把不该看的牌送到了
某个座位」。

新增 test/test_leak.js:跑 6 局(可查牌/不查牌 × 叫 65/70/5),对每一个
「服务器 → 某座位」的下发面(各 RPC 逐座位包 + 各阶段重连快照 + 明牌应答)
深度扫描出所有牌 id,逐个判定该座位此刻是否有权知道。结果 1814 个下发面 /
18706 次可见性判定,0 泄露。

变异检验:非 70 分把暗牌发给闲家(第三轮修过的历史缺陷)、重连把底牌发给
闲家、出牌包把剩余手牌发给所有人 —— 三条全部被抓住。

全套单测 520 → 523 项全绿。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 14:29:12 +08:00
joywayerandClaude Opus 5 9d0675fce8 二七王:第六轮核对(多局大局 + 整局带牌型模糊),未发现不一致
前五轮的端到端都只跑单局、且只出单张。本轮补两个从未被驱动过的维度:

一、多局大局(design §12.1 步骤10 / §12.2 / §4.6)
真实驱动 6 局与 12 局:跨局轮庄与「上局 banker+result」严格对应,另单独造出
result=0 的庄赢局验证连庄端到端(此前只有 do_prepare 的桩单测);每局零和、
累计分与逐局累加一致;account 只在末局出现,打满后再准备被拒;房卡只扣一次;
战绩载荷完整;中途解散按当前累计分结算、result=3。全部相符。

二、整局带牌型模糊(新增 test/test_fuzz.js)
test_endgame 的驱动器只会出单张,对子/拖拉机/甩牌/甩错在整局链路里从未跑过。
新测试用带牌型的对局补上,并对每一墩用独立参考实现重算「谁最大」与服务端
比对(不是抽查),另独立重算捡分、扣底倍数、算奖与捡分子数分配。探针阶段
跑了 160 局约 3800 墩(4 个种子)0 异常,入库版固定为 20 局约 480 墩、0.3s。

变异检验:牌的归属写给非胜者、单张毙牌不再压过副牌、算奖分配去掉 ×X、
跟牌牌面值改回未排序入参 —— 四条全部转红。

过程中修正了测试自身的三个问题(已写进 test/README 与 compliance):
- 参考实现的 rank 取了负数,而 0 是「不参与本墩」的哨兵,哨兵反而数值最大;
- 闲家捡分按 playowner 累加再与 aset.grade 比,是拿被测字段自证,playowner
  写错时两边一起错照样通过 —— 改成按独立算出的墩胜者累计;
- 扣底倍数再调 get_bottom_multiple 去比,同样是自证,倍数表改成恒返回 2 也
  通过 —— 改成按 design §6.3 独立重算。
另:该文件的覆盖下限是发牌相关的,随机发牌下扣底可能一次都不出现(实测 60
次里有 1 次),故把发牌也接到固定种子上;随机发牌的整局覆盖由 test_endgame
承担。

全套单测 511 → 519 项全绿,总耗时 < 1.7s。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 13:58:02 +08:00
joywayerandClaude Opus 5 1b76683704 二七王:固化两组 design 差分测试(§7 全量对拍 + §5.2 穷举差分)
把第五轮复验用的取证探针固化入库。两者都不枚举「我想到的场景」,而是把
design 的规则整条转写成参考实现再与代码大面积对拍,专治手写用例覆盖不到
的欠约束分支:

- test_calc.js:§7 算子全量对拍。参考实现逐字转写自 §7.1/§7.2/§7.3 判定表,
  比对 2 种算子模式 × 14 个叫分档 × grade 0~260 共 7308 格(每格比
  base/Q/判定倍率/最终子数),另按 design 的 17 张表逐格抽查 141 个写死的
  最终子数。断言按档位分组,失败可直接定位。
- test_followdiff.js:§5.2 跟牌强制层级穷举差分。对每手牌枚举全部 C 张出牌
  组合,逐个比对参考裁定与 can_followcard,约 11 万组。

两组均通过变异检验:关掉 follow_tractor_cover_ok → followdiff 三种拖拉机
首出全红;大光倍率 3→4 / 常规55档 base 4→5 / 爬坡40·35档 Q 20→40 → calc
精确指出档位与 grade。

过程中的教训已写进 test/README 与 compliance:差分测试的强度取决于造牌器。
第一版纯随机抽牌跑 7.8 万组全绿,但关掉覆盖度校验依然全绿——「同花色三组
互不相邻的两连对」这种唯一能区分「只出零散对子」与「先凑最长拖拉机」的
12 张结构随机抽不出来;掺牌又一度把它撑过枚举上限被静默跳过。故随机源改用
固定种子 PRNG,关键结构用确定性 structHands() 钉死。

全套单测 401 → 462 项全绿,总耗时 < 1.5s。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 12:56:30 +08:00
joywayerandClaude Opus 5 681be60e20 二七王:design 全量复验(无新增不一致)+ 补端到端整局单测
对 E1~E3 修复后的实现做取证式复核:把 design 的判定语句做成可执行探针直接
打在代码上(§5.1/§5.2 跟牌层级、§8.1 算奖连对链、§7 算子逐档、§5.4 甩牌最大性、
§6.3 扣底、§8.4 三条支付线、§4/§9/§10/§11 流程与门控),未发现新的不一致。

新增 test/test_endgame.js:用真实发牌跑完整一局(叫分→上庄→选主→埋牌→28 轮
出牌→小局结算)并校验与牌面无关的不变量(牌张守恒 84/8/16、捡分=闲家赢得分牌
+扣底分、X 分配庄±2X/闲∓X、算奖 X×(2Ni−Nj−Nk)、零和、result 与判定一致),
另覆盖投降局与中途解散两条支线。连跑 10 次无抖动,全套单测 389 项通过。

合规文档补记「第四轮·复验」取证表。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 19:47:01 +08:00
joywayerandClaude Opus 5 916066ba96 二七王:修正 design 全量重核发现的 3 项不一致(亮牌快照/报无主下发面/甩牌张数上限)
- §8.2 亮牌改用埋牌后 28 张静态快照 get_seat_cards_award,不再用
  get_seat_cards(只含未出的牌)——否则闲家重连时 get_deskinfo 按庄家
  当前剩余手牌重算,亮牌统计缩水甚至变 null。
- §9 出牌包由只带出牌者一家的 info 改为整表下发三家 seatlist,与重连包
  PushCards.seatlist 同名同构;报无主后另两家的主牌数/对子数不再滞后两次出牌。
- §5.4.3 甩牌"无组合数量限制":can_playcard 去掉规则外的 14 张硬上限,
  改为结构性上界 28(单人手牌上限,牌型编码在此范围内不溢出)。

协议文档同步改写 chupai 三处 info 条目与 liangpai 口径;合规文档补记第四轮
核对(流程层无缺环,规则层 3 项已收口)。全套单测 368 项通过。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 19:33:06 +08:00
joywayerandClaude Opus 4.8 339e6e99e1 二七王测试:完成 P2 用例,达成测试计划 DoD
- test_deal.js(新):§2 发牌构成——92张/去3-4共16/三家各28+底8/分值(§6.1)
- test_arith.js:§3 编码排序(order_cards 降序=设计顺序、is_continuous 相邻链逐段+反例)、
  §7 每档小光/过庄分界+升3级补齐
- test_paiju.js:§8.2 亮牌更多边界(6个7仅qi、固定主9→null、固定主10仅zhu)
- test_config.js:§10 直接调 export.get_asetcount/get_needroomcard(_joinroom)
- test_rpc.js/_rpc.js:§12 端到端(真实驱动 叫分→上庄→选主→埋牌→出牌ready)、
  §9 maipai 亮牌门控 + get_deskinfo PushCards 门控
- 02-测试计划.md/README:P2 与 DoD 标记达成

全部单测 204 项断言全绿(node server/games/erqiwang/test/run.js)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 01:24:34 +08:00
joywayerandClaude Opus 4.8 6939e70ed7 二七王测试:完成 P1 用例(L3 RPC 层 + 坐庄轮换)
- mod.js:加 module.exports 守卫,使其可被 Node require(友乐无 module 跳过)
- test/_rpc.js(新):L3 脚手架——挂类全局、mock cls_mod/min_loadJsFile 装配 mod.js、
  捕获 SendPack/sendpack_toother 下发包
- test/test_rpc.js(新):§9 明牌 mingpai(合法/不查牌·未报无主·非出牌阶段拒 + others结构)、
  §9 出牌 chupai 的 info/baozhu 查牌门控(可查有/不查无)、§4 投降 touxiang 条件(70·step2·庄家)、
  §4.2 mod.jiaofen 入参校验(>70/非5倍/首家必叫/后叫更低)、
  §4 70分上庄暗牌亮牌(真实 jiaofen 驱动到上庄,验证 bottomcards/ancard3s 门控)
- test/test_desk.js(新):§4.6 坐庄轮换 do_prepare(庄赢连庄/闲赢·投降下家)
- 02-测试计划.md/README:P1 标记完成,剩余归入 P2

全部单测 156 项断言全绿(node server/games/erqiwang/test/run.js)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 01:14:33 +08:00
joywayerandClaude Opus 4.8 0049754988 二七王测试:完成 P0 用例(正常跟牌/结算集成/叫分坐庄/扣底触发)
- test_follow.js(新):§5.1/5.2 正常跟牌/毙牌/垫牌 17 例——单张/对子/拖拉机的
  必出、缺门毙牌数量对应(副单→主单/副对→主对/副N连→主N连)、垫牌、有对/拖却出散张被拒
- test_callgrade.js(新):§4.2 叫分坐庄 do_callgrade 6 例(叫5立即/两家不叫/后叫更低)
- test_paiju.js:§7/§8 结算集成扩充(大光/过庄/升级/爬坡/傍王+算奖参与/对照)、
  §6.3 扣底触发 get_bottom_account(主对×2/两连对×4/副牌不扣/庄赢不扣)
- 02-测试计划.md/README:P0 全部标记完成

全部单测 123 项断言全绿(node server/games/erqiwang/test/run.js)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 01:03:01 +08:00
joywayerandClaude Opus 4.8 5a5165a319 二七王:制定服务端合规测试计划
- docs/compliance/02-测试计划.md:按 design 章节的"规则→用例"覆盖矩阵
  (标注被测函数/测试层L1-L3/正反边界/覆盖状态),缺口清单按优先级排序,
  以及 L2 局内集成 / L3 RPC 层所需脚手架
- test/README.md:链接测试计划

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 00:02:52 +08:00
joywayerandClaude Opus 4.8 6d663c8a66 二七王:新增 Node 单元测试,CLAUDE.md 记录测试命令
- test/_shim.js:平台全局垫片(min_ary_include/deduct、min_random/now/ontimeout、
  youle_erqiwang.import mock),忠实复刻 minhttp.js;仅测试用,不进正式代码
- test/_assert.js + run.js:极简断言与总运行器
- test/test_arith.js(扣底/算子常规+爬坡/算奖/甩牌/跟牌分量) test_config.js(位串/局数扣卡)
  test/test_paiju.js(亮牌/结算 get_paiju_account 集成),共 89 项断言全过
- test/README.md:运行方式与双运行时原理
- CLAUDE.md:常用命令补测试入口,说明服务端双运行时规范

(CLAUDE.md 内另含此前一处措辞微调,随本次文档更新一并纳入)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 23:51:12 +08:00