From ee658716941a1c80874e0849dba63ad211c9d7fe Mon Sep 17 00:00:00 2001 From: Joywayer Date: Wed, 26 Aug 2026 22:25:19 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=8C=E4=B8=83=E7=8E=8B=EF=BC=9A=E6=89=8B?= =?UTF-8?q?=E7=89=8C=E6=A0=87=E8=AE=B0=E7=B2=BE=E7=81=B5=E6=89=A9=E5=88=B0?= =?UTF-8?q?=E4=B8=8E=E6=89=8B=E7=89=8C=E4=B8=80=E4=B8=80=E5=AF=B9=E5=BA=94?= =?UTF-8?q?=EF=BC=8836=20=E4=B8=AA=EF=BC=89=EF=BC=8C=E5=B9=B6=E9=92=89?= =?UTF-8?q?=E6=AD=BB=E7=B2=BE=E7=81=B5=E6=80=BB=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 清单 §5.2 表格写的是「牌型分组标记 ×8」,但 §1.6 明确规定三种标记互斥、【每张牌】 至多一个,core/CardMark.js 也是按每张牌返回标记的。一手 28 张牌通常带 13 个以上标记、 36 张埋牌手更多,8 个远远不够。§1.6 是行为规格、比表格措辞更权威,故按 §1.6 裁决: HAND_MARK_1..36 与 HAND_CARD_1..36 一一对应。 - ID 另起 2100–2135 整段空号:1236 往后接不下 36 个连号(1250 起已是底牌/埋牌区), 换空号段比给别的 View 重新编号更安全;仍落在子游戏段 1001–2999,无重复。 - 守卫补「手牌与标记 1..36 一一对应且同群组」检查。 - 精灵总数由「> 200」改为钉死 387(test_constants / test_spriteindex 两处同一个数), 布局节点数同理已钉死——松下界删掉整个 View 都还能通过。 Co-Authored-By: Claude Opus 5 (1M context) --- .../01_SubGame/codes/config/Sprites_Cards.js | 55 +++++++++++++++---- client/tests/test_constants.js | 20 ++++++- client/tests/test_spriteindex.js | 3 +- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/client/js/01_SubGame/codes/config/Sprites_Cards.js b/client/js/01_SubGame/codes/config/Sprites_Cards.js index 7339b1f..197b604 100644 --- a/client/js/01_SubGame/codes/config/Sprites_Cards.js +++ b/client/js/01_SubGame/codes/config/Sprites_Cards.js @@ -7,7 +7,7 @@ // 连号精灵逐条写全,不用循环生成——便于人逐张对照编辑器核对。 var EQW_Sprites = EQW_Sprites || {}; -//自己手牌区:36 张手牌 + 8 个牌型分组标记,同属群组 210(清单 §5.2,Layer 102) +//自己手牌区:36 张手牌 + 36 个手牌标记(每张牌一个,见下方裁决说明),同属群组 210(清单 §5.2,Layer 102) EQW_Sprites.HandView = { Layer: EQW_Layers.HAND, //102 @@ -52,15 +52,50 @@ EQW_Sprites.HandView = { HAND_CARD_35: 1234, HAND_CARD_36: 1235, - //—— 8 个手牌牌型分组标记【T-8】,资源 EQW_Images.MARK_CARD_GROUP,帧1=拖(拖拉机) 帧2=橙五角星(正2/正7) 帧3=蓝五角星(其他主牌)—— - HAND_MARK_1: 1236, - HAND_MARK_2: 1237, - HAND_MARK_3: 1238, - HAND_MARK_4: 1239, - HAND_MARK_5: 1240, - HAND_MARK_6: 1241, - HAND_MARK_7: 1242, - HAND_MARK_8: 1243 + //—— 36 个手牌标记【T-8】,与 HAND_CARD_1..36 一一对应(HAND_MARK_i 属于 HAND_CARD_i)—— + //资源 EQW_Images.MARK_CARD_GROUP,帧1=拖(拖拉机) 帧2=橙五角星(正2/正7) 帧3=蓝五角星(其他主牌)。 + //【裁决:按「每张牌」而非「每组」】清单 §5.2 的表格写的是「牌型分组标记 ×8」,但 §1.6 明确 + //规定三种标记互斥、【每张牌】至多一个,core/CardMark.js 也是按每张牌返回标记的。 + //一手 28 张牌通常带 13 个以上标记、36 张埋牌手更多,8 个远远不够——§1.6 是行为规格, + //比 §5.2 表格的措辞更权威,故按 §1.6 扩到与手牌一一对应。 + //ID 另起 2100 段:1236 往后接不下 36 个连号(1250 起已是底牌/埋牌区), + //换整段空号 2100–2135 比给别的 View 重新编号更安全。 + HAND_MARK_1: 2100, + HAND_MARK_2: 2101, + HAND_MARK_3: 2102, + HAND_MARK_4: 2103, + HAND_MARK_5: 2104, + HAND_MARK_6: 2105, + HAND_MARK_7: 2106, + HAND_MARK_8: 2107, + HAND_MARK_9: 2108, + HAND_MARK_10: 2109, + HAND_MARK_11: 2110, + HAND_MARK_12: 2111, + HAND_MARK_13: 2112, + HAND_MARK_14: 2113, + HAND_MARK_15: 2114, + HAND_MARK_16: 2115, + HAND_MARK_17: 2116, + HAND_MARK_18: 2117, + HAND_MARK_19: 2118, + HAND_MARK_20: 2119, + HAND_MARK_21: 2120, + HAND_MARK_22: 2121, + HAND_MARK_23: 2122, + HAND_MARK_24: 2123, + HAND_MARK_25: 2124, + HAND_MARK_26: 2125, + HAND_MARK_27: 2126, + HAND_MARK_28: 2127, + HAND_MARK_29: 2128, + HAND_MARK_30: 2129, + HAND_MARK_31: 2130, + HAND_MARK_32: 2131, + HAND_MARK_33: 2132, + HAND_MARK_34: 2133, + HAND_MARK_35: 2134, + HAND_MARK_36: 2135 } }; diff --git a/client/tests/test_constants.js b/client/tests/test_constants.js index 0563f3e..1513768 100644 --- a/client/tests/test_constants.js +++ b/client/tests/test_constants.js @@ -41,11 +41,29 @@ t.eq('声音资源均 >= 101', soundVals.every(v => v >= 101), true); // T-20 // ---- 精灵 ID 1001–2999(段内 3000 已被平台占用,清单 §0.3)---- const index = EQW_SpriteIndex.build(EQW_Sprites); const spriteVals = Object.keys(index).map(k => index[k]); -t.eq('精灵数量 > 200', spriteVals.length > 200, true); +// 钉住精确数量:松下界(如 >200)删掉整个 View 都还能通过。 +// 增删精灵时连同本数字一起改——有意的顺手更新,不是有意的就红给你看 +t.eq('精灵总数', spriteVals.length, 387); const spriteOk = spriteVals.every(v => v >= 1001 && v <= 2999); if (!spriteOk) { console.log('越界精灵: ' + JSON.stringify(spriteVals.filter(v => v < 1001 || v > 2999))); } t.eq('精灵落在 1001-2999', spriteOk, true); +// ---- 手牌标记与手牌一一对应(清单 §1.6:三种标记互斥、【每张牌】至多一个)---- +// core/CardMark.js 也是按每张牌返回标记的:一手 28 张常带 13 个以上标记、36 张埋牌手更多, +// 标记精灵必须与手牌等量,否则渲染时必然有牌的标记画不出来 +const groupMap = EQW_SpriteIndex.buildGroupMap(EQW_Sprites); +const handPairing = []; +for (let i = 1; i <= 36; i++) { + if (!index.hasOwnProperty('HAND_CARD_' + i)) { handPairing.push('缺 HAND_CARD_' + i); } + if (!index.hasOwnProperty('HAND_MARK_' + i)) { handPairing.push('缺 HAND_MARK_' + i); } + else if (groupMap['HAND_MARK_' + i] !== groupMap['HAND_CARD_' + i]) { + handPairing.push('HAND_MARK_' + i + ' 与手牌不同群组'); + } +} +if (handPairing.length) { console.log('手牌标记配对问题:\n ' + handPairing.join('\n ')); } +t.eq('手牌标记与手牌 1..36 一一对应', handPairing, []); +t.eq('手牌标记恰好 36 个(无第 37 个)', index.hasOwnProperty('HAND_MARK_37'), false); + // ---- 各类 ID 全局不重复 ---- function dupsOf(vals) { const seen = {}, dups = []; diff --git a/client/tests/test_spriteindex.js b/client/tests/test_spriteindex.js index 3c88a73..51e624a 100644 --- a/client/tests/test_spriteindex.js +++ b/client/tests/test_spriteindex.js @@ -82,6 +82,7 @@ let realOk = true; let realIndex = {}; try { realIndex = EQW_SpriteIndex.build(EQW_Sprites); } catch (e) { realOk = false; console.log('建索引失败: ' + e.message); } t.eq('真实精灵常量无重复键', realOk, true); -t.eq('真实精灵数量 > 200', Object.keys(realIndex).length > 200, true); +// 钉住精确数量(与 test_constants.js 同一个数):松下界删掉整个 View 都还能通过 +t.eq('真实精灵数量', Object.keys(realIndex).length, 387); process.exit(t.done('spriteindex') ? 0 : 1);