Commit Graph
7 Commits
Author SHA1 Message Date
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 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 5 a4a8eb8408 二七王:补齐客户端牌id入参校验(重复/越界/非数组)
check_cards_inhand 此前只逐个校验牌id是否在手上,不查重复、不查
类型与范围,且在牌已出/已埋时 return 空值而非 false,造成两个可
被利用的缺陷:

1. 重复牌id 可伪造牌型:do_playcard([方块K,方块K]) 实测返回
   result=true、cardtype=201(同一张牌被判成一对),可进而伪造
   拖拉机与甩牌分量,本轮结算时该分牌的 score 还会被重复累加。
2. 埋牌传 8 个相同 id 实测只埋下 1 张,庄家带 35 张进入出牌阶段,
   整局牌数错乱。
3. 越界 id 或非数组入参会在解引用处抛异常,中断 DoPack。

新增 check_cards_valid 作为唯一入参校验入口(非空数组、元素为本
局牌表内的整数牌id、互不重复),由 check_cards_inhand 先行调用;
mod.maipai/mod.chupai 在读取 cards.length 之前先过该校验。按
engineering §03「显式失败优于隐式兜底」直接拒绝,不做类型兜底。

新增 test_input.js 28 项正/反/边界用例回归上述三点。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 04:10:15 +08:00
joywayerandClaude Opus 4.8 60271175d6 二七王:逻辑文件补双运行时守卫,解锁 Node 单测
按 dev-guide 01 §1「一套代码,两个运行时」补齐 erqiwang 缺失的守卫(此前只支持友乐全局加载模型):
- 顶部:跨模块依赖走 `if (typeof require!=='undefined') var X=require('./class.X.js')`
  (config/pai/arith 无跨模块依赖;paiju 依赖 arith/config/pai;desk 依赖 paiju;export 依赖 arith/config/desk)
- 底部:`if (typeof module!=='undefined') module.exports = cls_X`
- export/import 的平台接线 `youle_erqiwang.X=...` 加 `typeof youle_erqiwang` 守卫,Node 无此全局时跳过

纯增量:友乐无 require(浏览器模型),守卫全部跳过、全局名仍无条件暴露,线上行为不变;
仅在 Node 下额外启用 require/module.exports,从而可用 node 直接单测。min_*/youle_erqiwang 等平台全局仍按全局名引用(Node 侧由测试 shim 提供)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 23:51:12 +08:00
joywayerandClaude Opus 4.8 257615aed9 二七王:实现 §5.4.4 强制跟牌分量拆解
原缺陷:混合甩牌在 can_playcard 牌型计算中被塌缩为扁平"多单张/多对",
跟牌只强制"同花色凑张数",未强制"拖拉机→对子→单张"的分量优先级。

修复:
- 合法甩牌时 can_playcard 记录分量需求 shuai_demand{tractors,pairs,singles},
  do_playcard 存入 playproc、new_playround 复位
- 新增 arith.flush_follow_ok:在"同花色凑张数、主牌最大化"之上追加逐分量强制匹配
  ——能凑同长主拖必凑、能凑主对必凑(不足则退化为对子/单张),不得拆散去垫
- 新增 arith.remove_pairs 辅助
- 跟牌时 do_playcard 在 can_followcard 通过后再过 flush_follow_ok

不影响捡分/输赢(合法甩牌仍恒不可反超),仅补齐闲家被迫垫牌的结构约束。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 23:20:09 +08:00
joywayerandClaude Opus 4.8 6120580505 二七王服务端:按 design.md 整改结算/算奖/甩牌,roomtype 改位串
结算与算奖(§6.3/§7/§8)
- 扣底倍数改线性:单张×1、主对×2、N连对×2N
- 算子实现常规算子 + 爬坡两套(大光×3、Q=40 / 爬坡分段),X=基础子数×判定倍率
- 常规算奖只计庄家;连对链修复(传实际主花色);移除 ≥10 老主误加奖与设计外的
  「冲关必叫/四王必踢」作废;算奖快照取庄家埋牌后28张(新增 get_seat_cards_award)
- 算奖并入结算改为 X×(2Ni−Nj−Nk);傍王按房间开关、庄闲每王1奖

出牌与甩牌(§5.4)
- 副牌绝对禁甩;甩牌最大性按对手全部手牌逐分量判定(新增 trump_rank/
  decompose_trump/opp_can_beat_flush);甩错惩罚(收回、只打最小一张、下发 shuaicuo)
- 修复 can_followcard 引用未定义 tuolaji_list 的崩溃、can_playcard 14张上限失效

开局/投降/暗牌(§4)
- 投降改为选主阶段(step2)与选主互斥、不埋牌、算奖用庄家36张;埋牌后直进出牌(删废弃step4)
- 70分暗牌摸牌前向所有玩家亮3秒(+ancard3s),非70分不再泄露暗牌给闲家;叫分上限≤70

查牌/亮牌(§8.2/§9)
- 新增亮牌 get_liangpai(庄家埋牌后28张按阈值统计);报无主统计与亮牌按查牌位门控
- 新增 mingpai 明牌 RPC(可查牌+已报无主时查看他家全部主牌)

房间与配置(§10)
- 局数6/12、房主扣卡2/4;新增 class.config.js 以位串解析 roomtype(唯一入口 SSOT)
- 清理 do_choiceflower 死代码

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-04 22:32:53 +08:00
joywayer 96372d713c 规则文档理清楚,开始代码层面对比和校对 2026-07-04 09:52:49 +08:00