 joywayerandClaude Opus 5
|
76e82405e1
|
二七王:S-6 大局结算按 基础分/冲关分/傍王分 三项分解
问题:大局结算面板要分项显示,而 account 只有「累积得分 + 每局得分数组」。
傍王分尤其拆不出来——N = 冲关奖数 + 傍王王数,两个来源【求和之后】才代入
grade_aw = X×(2Ni−Nj−Nk),事后无法反推各自占比。
解法:在算钱时就拆。把 N 分成 N_冲关(只计庄家)与 N_傍王(勾选后庄闲都算),
分别代入同一公式各算一次。公式对 N 线性,故恒有
grade_cg + grade_bw == grade_aw
这条恒等式正好当回归断言用。
服务端:
- class.paiju.js 抽出 award_pay(n) 复用同一公式,新增 grade_cg / grade_bw;
desk.seatlist 追加三个累计位(基础/冲关/傍王)。
- class.desk.js seatlist 初始化为 5 元素;account 下发改为【对象数组】
{ score, grades, grade_jf_total, grade_cg_total, grade_bw_total }。
原二元数组下标语义不清,且前端未开工,此时改代价最小(同 S-4 的判断)。
协议:aset.seatlist 增补 grade_cg / grade_bw;account 结构与恒等式
grade_jf_total + grade_cg_total + grade_bw_total == score 写明;
并记录这次结构变更的时间与理由。
测试(endgame 26 → 39 checks):
- 核心不变量:两分量之和 == grade_aw;两分量各自零和。
- 未勾傍王局:grade_bw 恒 0、grade_cg == grade_aw。
- 【新增一整局开傍王的端到端】:不开傍王时 grade_bw 恒 0,只验到平凡情形,
必须有傍王局才算真验证了拆分。该局逐项复核两个分量的公式、naward 口径,
并钉住「王数不全相等时 grade_bw 必有非零」防止又退化成平凡。
- 大局累计恒等式:基础+冲关+傍王 == 累积总分。
反向验证:把 _awbw 置零 → 4 条断言失败;把冲关分量误算到闲家头上 →
2 条断言失败。均已还原、全量 17 文件全绿。
另修四处测试桩:_rpc.js / test_paiju / test_rpc / test_success 里手工构造的
o_desk.seatlist 仍是 2 元素,未跟上 class.desk.js 的结构变更(脚本缺陷,
非业务缺陷)。
顺带解决小局结算「冲关分」标签的不严谨:改取 grade_cg 而非 grade_aw,
开傍王时不再把傍王贡献算进来。
遗留 T-31:参考图「基础分」与「总得分」两行数值相同且与右侧大字对不上
(30/30 vs +135),mock 不自洽。当前按 基础分=grade_jf_total、总分=score
提供。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-26 00:34:46 +08:00 |
|
 joywayerandClaude Opus 5
|
4aab71e6a3
|
二七王:实现 S-1 curmultiple 与 S-2 mustcard
S-1 当前抓分倍数(design §7.2.0):
- class.paiju.js 新增 get_curmultiple(),复用 get_qvalue + get_upgrade,
与结算 aset.upgrade 同源同算法,差别仅在不含扣底(末轮才产生)。
- 随现有包下发、不另开推送:shangzhuang / chupai1-3 / deskinfo.PushCards。
- 三家同值,整表下发不涉及泄露(捡分本就公开);叫分未定时为 0。
S-2 跟牌必出牌(design §5.2):
- class.paiju.js 新增 get_mustcard(seat),内部复用与出牌校验完全相同的
get_followcard,故建议与校验天然一致。
- 【只发给 nextseat 一家】:它是该玩家自己手牌的子集,整表下发会泄露
他家手牌结构(server 红线:发全 ≠ 发多)。
- 四种情形不下发:非出牌阶段、该座位是本轮首家、首家甩牌、必出牌为空。
甩牌一条尤其重要——甩牌跟牌走 flush_follow_ok 的逐分量匹配,与
get_followcard 不是同一条路径,给建议会给错。
测试(新增 test/test_hint.js,33 checks):
- curmultiple:算法层逐档对齐 design §7.2.0 判定表(含爬坡 Q 分段)、
三家同值、重连与出牌包一致、叫分未定为 0、与 get_upgrade 绝对值一致。
- mustcard:只有 nextseat 收到、另两家没有、内容确属收包者自己的牌、
首家无、缺门有富余时无、手牌数恰等于首家张数时整手必出、甩牌不发、
非出牌阶段不发、重连按 currseat 门控。
过程中修正的两个测试自身问题(均为脚本缺陷,非业务缺陷,业务判定经证据核实正确):
- 「缺门方无必出」原用例给闲2 只发 2 张牌,恰等于首家张数,get_followcard
正确判定为「整手必出」;改为发 4 张才留出选择余地,并补一条对照用例
锁住「恰等于张数则整手必出」这个正确行为。
- 「甩牌不发」「非出牌阶段不发」两条原本是假通过——桩的 startcount 仍是 -1,
前置守卫先返回了 null,根本没测到被测因素。改为先把桩推进到跟牌态、
每个用例只变动一个因素,并加一条「自证」用例确认推进后确实能算出必出牌。
另:mustcard 补进 test_leak.js 的 CARD_FIELDS 审计白名单(与 burycards 同理,
不加则误发不会被泄露审计发现)。反向验证:改成整表下发后,审计立刻报出
5 张越权牌;把 curmultiple 写死为 1 后,两条断言失败。均已还原、全绿。
协议文档同步 shangzhuang / chupai1-3 / PushCards 的字段说明。
至此 §7.5 服务端待补 5 条全部完成,服务端侧无遗留。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-25 20:25:32 +08:00 |
|
 joywayerandClaude Opus 5
|
ecec44e93a
|
二七王:S-4 拆分 bottomcards 字段名,S-5 术语同步收口
S-4(服务端改动):底牌与埋牌底牌不再共用一个字段名。
- bottomcards = 底牌(发牌留桌 8 张)—— shangzhuang / ChooseMain / BuryCards,保持不变
- burycards = 埋牌底牌(庄家埋下 8 张)—— maipai(mod.js)、PushCards(class.export.js)
- 结算 bottom.cards 未改名(分组名已表明是抠底相关),文档注明其语义
测试:
- test_leak.js 的 CARD_FIELDS 白名单加入 burycards。这一步是必须的——不加的话
新字段会静默脱离下发面审计,闲家误收也发现不了。
- test_rpc.js 新增 11 条正反用例:庄家有 burycards 且为 8 张、庄家不再有
bottomcards(抓改名漏改)、闲家两个字段皆无、重连 PushCards 同上。
验证(不止「跑过了」):
- 改动前基线 16 个文件全绿;改动后仍全绿,新增后 rpc 从 89 → 100 checks。
- 反向验证一:把 mod.js 的 burycards 改回 bottomcards → test_rpc 新用例 FAIL,
且 test_leak 报出真实泄露(赋值改了而 delete 没改时,闲家会收到庄家埋的牌)。
- 反向验证二:删掉闲家侧的 delete msg.data.burycards → test_leak 立刻抓出
5 张越权牌,确认 burycards 确已纳入审计白名单。
两次验证后均已还原并复跑全绿。
S-5:术语同步收口。design.md / packet_protocol.md / 代码注释均已改用
「底牌 / 埋牌底牌」;compliance 三份历史核对记录有意不改(反映当时的 design
表述,下轮核对按新 design 重做)。
另:T-9 亮牌条文案暂定「x对 x主」(取 liangpai.zhupair 与 zhu,其余档位
先不渲染、协议不变)。至此 29 项待确认规格全部有结论。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-25 18:07:17 +08:00 |
|
 joywayerandClaude Opus 5
|
a4361a802d
|
二七王:补 9 处 design 规则的正/反/边界用例(均通过变异检验)
对 design §1~§12 重做「每条规则是否三类用例齐全」的审计。此前的覆盖矩阵按
「被测函数」组织,容易漏掉跨函数才体现的规则,本轮补齐 9 处:
- G1/G2 §4.2 叫分:下限5与非首家不叫接受,负数/缺call/步进外/同分拒;
「不叫即退出本局叫分」——反悔再叫被 SEAT 拒、callproc 不变、仍轮到下一家
- G3 §4.5 埋牌:非庄家 SEAT、step2/step5 STEP、7张/9张/空数组 PARAM
- G4 §5.1 每轮由上一轮牌面最大的一方先出(闲1赢/闲2赢两种)
- G5 §6.2 闲家赢计入台面全部分牌(含庄家自己打出的)、庄家赢作废、
两个闲家谁赢结果一致
- G6 §8 算奖快照:庄家埋后28(已埋不在内)、闲家28、投降36、打出后不缩水
- G7 §3 对子只认同花色同点数两副:跨花色副7/副2、正副7、大小王均不成对
- G8 §6.3 赢末轮的牌不全是主牌就不扣底(副牌拖拉机/混合出牌/顺序颠倒)
- G9 §11 无超时托管守卫:对局阶段 min_ontimeout 调用次数必须为 0,
将来有人加超时代打就会转红
每条都在副本上注入违反该规则的改动确认转红(7 组变异全部被抓住)。
顺带修一个测试自身的问题:mkBury 桩缺 do_burycard,导致「埋牌张数校验被
改松」这类变异表现为整个文件崩溃而非某条断言转红,后续断言全不执行。桩已
补完整到能走完成功路径。
全套单测 462 → 511 项全绿。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-23 13:36:09 +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 5
|
35affa7c20
|
二七王:不可查牌模式屏蔽出牌历史(design §9 消歧义 + 代码门控)
design §9 原文把可查牌模式的四项功能列成无序列表,不可查牌只写
「不提供以上任何查看 / 明牌功能」,随后展开的例子却只提了主牌数量、
对子结构、明牌按钮、亮牌统计,没提第一条「已经打出的牌可以查看」,
导致"以上"的范围有歧义。代码据此照发出牌历史,前一轮核对把它记为
待确认项(01 表 D6)。
规则设计者已确认:**不可查牌模式必须屏蔽出牌历史,只有可查牌模式
才能查看**。据此:
- design §9 改写为无歧义表述:先给出「查牌 = 回看不该随时可见的信
息」的定义,把可查牌的四项功能编号列出(① 出牌历史 ② 报无主后的
他家主牌数/对子数 ③ 明牌 ④ 庄家亮牌),不可查牌逐条对应说明一项
都不提供;并补一段边界说明——**当前这一轮桌面上的牌两种模式下都
必须可见**,否则后出的人无从跟牌、无从判断本轮谁最大,断线重连同
理(当前轮照常恢复,往轮历史按模式开关给不给)。
- class.export.js:get_deskinfo 的 PushCards.pushlist 构建与排序整
体移入 `if (!cfg.nocheck)`,不查牌时不带该属性;当前轮桌面牌由
PushCards.playproc.cards 恢复,两种模式都有。
- 协议文档:pushlist 补「仅可查牌模式下有此属性」,playproc 补「两
种模式恒有」及其原因。
- 合规文档:01 表 D6 由「待确认/未修」改为已确认并修复,从「尚未处
置」移出;02 测试计划断言总数 357→361 并新增该维度覆盖行。
test_rpc 新增 4 项:不查牌房无 pushlist、可查牌房有 pushlist,且两
种模式下当前轮桌面牌 playproc.cards 都能恢复。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-16 18:55:33 +08:00 |
|
 joywayerandClaude Opus 5
|
8948a2950f
|
二七王:chupai1 下发甩牌分量构成 shuai
cardtype 只能表达单一牌型(1xx 单张 / 2xx 对子 / 3xx 拖拉机),而
甩牌是单张、对子、拖拉机自由混搭(design §5.4.3),会被 can_playcard
的牌型推导压平——例如「主K对 + 主5」得到 103、「两连对 + 散对」得到
203,客户端拿到 cardtype 无从还原分组,甚至看不出这是一次甩牌。
服务端本就已经算出了分量需求 shuai_demand(供跟牌逐分量强制匹配,
design §5.4.4),按「每个下发包必须携带前端界面所需的全部核心数据」
一并下发:chupai1 在合法甩牌时带 shuai = {tractors,pairs,singles},
非甩牌与甩错退化为单张时不带此属性。
test_rpc 新增 8 项:合法甩牌带 shuai、非甩牌不带、甩错只打最小一张
且不带 shuai。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-12 04:21:11 +08:00 |
|
 joywayerandClaude Opus 5
|
4276d38267
|
二七王:报无主后立即为全体三人刷新主牌统计
design §9:「一旦有玩家的主牌全部打空,系统就为全体三人显示另外
两家各自的主牌数量、以及这些主牌里有多少对子」。
原实现只在出牌者自己出牌时更新自己那一格 seatlist[seat][4],所以
A 打空主牌报无主的那一刻,B、C 的主牌数/对子数仍是初始 [-1,-1],
要等各自轮到出牌才补上,界面最多滞后两次出牌才完整。
改为:出牌后先判定出牌者主牌是否出空,一旦 have_baofu() 成立,就
按各家实际手牌为三个座位统一重算 [剩余主牌数, 剩余主对数] 及主花
色标志。重算幂等——主牌一旦出空不会再有,[4][0] 恒为 0。
test_rpc 的 mkChupai 原先只把 seatlist[1][4][0] 置 0 伪造报无主,
而不真的清空 seat1 的主牌;新逻辑按实际手牌重算会把这个假状态纠
正回去,导致 baozhu 断言失败。这是新实现更严格的正确表现,故改测
试造真状态(把 seat1 的主牌标为已出),不是放宽断言。
test_input 新增 6 项:报无主前三家均为 [-1,-1];打空瞬间三家统计
与主花色标志同时刷新到实际值。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-12 04:20:03 +08:00 |
|
 joywayerandClaude Opus 5
|
84774fa525
|
二七王:修正重连出牌历史 pushlist 的结构与排序
get_deskinfo 的 PushCards.pushlist 排序段有两处错:
1. 内层循环上界误用 pushlist.length(轮次数)当座位数。轮次 >3 时
会给内层数组写入下标 3..轮次-1,把本应恒为 3 个座位的数组撑成
轮次长度并填满 undefined;轮次 <3 时又漏排后面的座位。实测 5 轮
时内层长度变成 5 且含 undefined。
2. 排序传的是上一个 for 循环泄漏出来的 pai.flower。循环结束后 pai
指向牌表最后一张(大王,flower=5),等于按「无主牌花色」排序,
主牌不会排到副牌前面。
改为内层固定 3 个座位、按 paiju.flower 排序,并对缺失轮次加守卫。
test_rpc 新增 4 项:轮数、内层恒 3、无 undefined,以及排序判别用例
(seat0 同轮出「主5 + 副♥A」,主5 必须在前——旧代码下 副A 会排前)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-12 04:18:30 +08:00 |
|
 joywayerandClaude Opus 5
|
20b5425a65
|
二七王:下发面 multiple 按房间「爬坡」开关取值
arith.get_multiple_bycall 写死 get_base_bycall(call, false),被
mod.jiaofen(jiaofen/shangzhuang 两个包)与 export.get_deskinfo
的叫分/选主/埋牌/出牌四个阶段共 6 处使用,且都不传 roomtype。
后果:爬坡房里对局全程界面显示的是常规算子子数,与结算包
aset.multiple 不符。例如叫 45 分,界面显示 6 个子、结算按
design §7.3.1 实际是 7 个子。违反 server dev-guide「服务器权威 +
每个下发包必须携带前端界面所需的全部核心数据」与 engineering
SSOT(同一业务数据只有一个计算处)。
移除 get_multiple_bycall 这层写死 climb=false 的兼容包装,全部
改为直接调 get_base_bycall(call, cfg.climb),cfg 由
class.config.parse(o_room.roomtype) 得到——与结算处
get_paiju_account 用的是同一个取值入口。get_deskinfo 内顺带复用
同一份 cfg,去掉 PushCards 分支里重复解析 roomtype 的调用。
test_rpc 新增 7 项:叫 45 分在常规房/爬坡房分别驱动到上庄,断言
上庄包与重连 ChooseMain 的 multiple 为 6/7,并与结算包
aset.multiple 逐一对齐。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-12 04:16:42 +08:00 |
|
 joywayerandClaude Opus 5
|
c2a375eef5
|
二七王:补齐 data.success 成败标志与失败回包
此前全仓(除协议文档开头一句说明外)没有任何下发包携带
data.success,且所有失败路径一律裸 return、不回任何包:前端点了
没反应,只能干等倒计时,同时违反 server dev-guide「成败标志唯一
是 data.success,主动推送的 data 必须自带 success」与 client
dev-guide「发包只请求、收包才表现」两条硬红线。
本次:
- 成功包一律补 data.success=true:fapai、zhunbei(class.desk.js)、
jiaofen、shangzhuang、xuanzhu、maipai、chupai1/2/3、mingpai、
tishi(mod.js),jiesuan 在 get_paiju_account 统一注入(覆盖
正常/投降/解散三种结算来源)。
- 新增 youle_erqiwang.ERR 失败码表与 do_sendfail 统一回包封装:
PLAYER/NODESK/STEP/SEAT/PARAM/RULE,失败只回发给请求者
(conmode/fromid 取自请求包),data.success=false + errcode。
- 每个 handler 的每条失败分支都改为「回失败包 + return」,含
check_player 不通过(平台侧只返回 null、不回包,前端会干等)。
tishi 成功时仍按 design §11 只转发给对家、不给发送者回执(该包不
含对局状态,属 fire-and-forget 提示),失败才回给发送者。
test_rpc 中原先以「不发包」表示被拒的断言,同步改为断言「恰好回
1 个 success=false 且 errcode 正确的包」——是随行为修正而加强,
不是软化。新增 test_success.js 29 项覆盖成功包 success 字段与各
handler 失败回包。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-12 04:15:31 +08:00 |
|
 joywayerandClaude Opus 4.8
|
9456ab9319
|
二七王:实现 §11 闲家三提示(踩/没分/有分) + 明确副7/副2 成对语义
全面符合性再审查(4 维度独立对抗核对)结论:与计分/发牌/出牌/跟牌/甩牌
相关规则均一致,无缺陷;仅 §11 闲家三提示服务端缺失、副7/副2 异花色
成对语义存疑两项待办。本次按用户裁定落地:
1. §11 三提示(新增 mod.tishi):闲家在出牌阶段(step5)发 踩/没分/有分,
服务端不校验真实性、只 SendPack 转发给对家(另一闲家 3-banker-seat);
庄家无对家不参与;非法 tip/非出牌阶段/庄家发均拒。
协议补 packet_protocol §13.7/13.8;test_rpc +11 例(正反+边界)。
2. 副7/副2 成对语义:裁定"只同花色同点数两副成对"(代码本已如此,无需改),
在 design §3 补说明闭合该反复出现的存疑(异花色副7 不成对)。
compliance 文档同步:§11 状态转✅、首轮结论摘要加"非当前状态"说明、
计数 259→270。全套 270 项断言全绿(rpc 34→45)。
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-05 16:39:04 +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 |
|