Commit Graph
9 Commits
Author SHA1 Message Date
joywayerandClaude Opus 5 ce4c972b7b 二七王:修复跟牌判定依赖客户端入参顺序(可翻转本轮胜负与结算)
can_followcard 尾段计算 cardvalue/noflower/nopair 时用的是入参原始数组
followcards(客户端提交顺序),而 get_pairlist/get_tuolaji_list 都按降序
相邻取对。端到端实测:闲家用主拖拉机毙牌且为末轮,降序提交时闲家赢下本轮
(捡分 40、扣底 ×4),把同一手牌打乱成 [51,50,105,104] 后对子漏判、
cardvalue 归 0,变成庄家赢、闲家 0 分大光、不扣底——同一手合法牌仅靠数组
顺序就能翻转胜负、捡分归属与最终结算,同源问题还能抹掉 noflower 缺门标志
污染 §9 下发给全场的牌况表。

改为在 min_ary_deduct 削减 _followcards 之前另存完整排序快照 _sortfollow,
尾段 8 处全部改用它(_followcards 会被削减、不可复用)。

顺带给 get_disbandRoom 加空守卫:平台在 makewar 后立刻置 battlestate=1,
而首局是延迟 1 秒创建的,这段窗口内解散会在 curr_paiju() 的 undefined 上
解引用抛异常、打断平台解散链路;现返回 null 走平台既有的「不带 deskfree」分支。

补 8 条回归(入参顺序无关性 5 条 + 端到端 1 条 + 解散空守卫 2 条),
已用「回退修复 → 用例转红」反验有效性;全套单测 401 项全绿。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-23 12:18:04 +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 5832b781c8 二七王:is_continuous 的 8→6 相邻补花色校验
design §5.3 的「6 与 8 可组成拖拉机」是同花色内的相邻关系,但
is_8/is_6 只判 code % 100,不校验花色,导致
is_continuous(♥8=308, ♣6=206) 与 is_continuous(主8=1408, ♣6=206)
都返回 true。

影响面:get_chongguan 是唯一会拿整手牌(含各花色副牌)去扫描连对
链的调用点,连对链走到主 8 之后,手里任意花色的一对 6 都会被误判
为连续、多算 1 奖,并把链锚点带进副牌继续错误延伸(design §8.1
明确 A 到 5 这一段必须是选定花色的主牌)。其余调用点入参都是同花
色牌表或纯主牌表,不受影响。

改为要求牌编码相差 2(同花色的 8 与 6 恒差 2,跨花色差 100 的倍
数),并保留 is_8/is_6 守卫以免把「主A-主Q」这类差 2 组合放行。

test_arith 新增 5 项:同花色 8-6 连、三组跨花色 8-6 不连、差 2 但
非 8/6 的组合不连。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-12 04:17:32 +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 4.8 21e76b976a 二七王修复:拖拉机跟牌降级递归 else 分支欠约束(放行非法跟牌)
get_followcard 降规格递归中,当某级"等长短拖拉机候选总对数 > 剩余需求"
时(class.arith.js else 分支),因 cantype 单一结构模型无法表达"任选其一
成拖拉机、其余自由",直接返回宽松的"任意 N 对",导致跟牌方明明有 2 连对
却被允许只出三个孤立对子(如首家 3 连对、跟牌方 AA KK JJ TT 88 66 时打
AA JJ 88),违反 design §5.2"能凑多长拖拉机就必须先凑多长"。

方案 2(根治,不引入过约束):在 can_followcard 结构校验后新增"最大拖拉机
覆盖度"闸门 follow_tractor_cover_ok——
- tractor_run_lengths:把同花色对子按相邻拆成连对 run 长度表;
- max_tractor_profile:贪心最长优先取 K 对,得字典序最大规格档案 best;
- profile_less:跟牌自身档案 got 不得字典序劣于 best,否则拒。
仅在"跟牌整手=首家花色对子且该花色牌≥首家张数"时生效,垫/混合/对子不够
等一律放行。can_followcard 是唯一出牌闸门(paiju.js:605),覆盖人工+托管。
get_followcard else 分支加注释指明由该闸门兜底。

回归测试:test_follow.js +5 条(303/304 三组 2 连对场景,含 else 欠约束
回归:出孤立对→拒、出尽量长拖→合法)。全套 259 项断言通过。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-05 07:18:42 +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