// roomtype 位串解析 + 局数/扣卡映射(design §10.1) require('./_shim'); const C = require('../class.config.js'); const t = require('./_assert')(); // 复刻 export 的两个映射(现为2行)做端到端验证 const needroomcard = rt => { const c = C.parse(rt); return c.deductAA ? (c.aset12 ? 2 : 1) : (c.aset12 ? 4 : 2); }; const asetcount = rt => { const c = C.parse(rt); return c.aset12 ? 12 : 6; }; // --- parse 位串 --- t.eq('"00000"', C.parse("00000"), { aset12: false, deductAA: false, bangwang: false, climb: false, nocheck: false }); t.eq('"10100"', C.parse("10100"), { aset12: true, deductAA: false, bangwang: true, climb: false, nocheck: false }); t.eq('"01011"', C.parse("01011"), { aset12: false, deductAA: true, bangwang: false, climb: true, nocheck: true }); t.eq('"" 兜底', C.parse(""), { aset12: false, deductAA: false, bangwang: false, climb: false, nocheck: false }); t.eq('undefined 兜底', C.parse(undefined), { aset12: false, deductAA: false, bangwang: false, climb: false, nocheck: false }); t.eq('"1" 短串(位长校验后按缺省)', C.parse("1"), { aset12: false, deductAA: false, bangwang: false, climb: false, nocheck: false }); // --- 【位长协议 · 2026-09-01 升级 · 第 2 版】扩展位在末尾 --- // 新版:N+5 位 = 前 5 位协议位(IDX_ASET..IDX_NOCHECK,对应 charAt 0..4)+ 后 N 位扩展位 // 字串示例:'11011' + '000000' = '11011000000'(默认 N=6 扩展位全 '0') // 协议位的位索引(IDX_* = 0..4)永远不变,扩展位在协议位之后。 // 兼容性:旧版 5 位字符串直接走 charAt(0..4);新版 11 位也走 charAt(0..4)(自动兼容)。 // 前端发 11 位 = 5 位 buildRoomType() 右补 6 位扩展位,服务端按 charAt(0..4) 读协议位。 t.eq('新版 11 位 "10100000000"(前 5 位 10100 = 12局+房主+傍王)', C.parse("10100000000"), { aset12: true, deductAA: false, bangwang: true, climb: false, nocheck: false }); t.eq('新版 11 位 "11011000000"(前 5 位 11011 = 12局+AA+不查+爬坡)', C.parse("11011000000"), { aset12: true, deductAA: true, bangwang: false, climb: true, nocheck: true }); t.eq('新版 11 位 "00000000000"(前 5 位 00000 = 全默认)', C.parse("00000000000"), { aset12: false, deductAA: false, bangwang: false, climb: false, nocheck: false }); // 兼容性:旧版 5 位 roomtype t.eq('旧版 5 位 "10100"(无扩展位)直接解析', C.parse("10100"), { aset12: true, deductAA: false, bangwang: true, climb: false, nocheck: false }); // 兼容性:未来位长增加(追加更多扩展位)→ 前 5 位协议位不变 t.eq('17 位 "11011000000000000"(前 5 位 11011)', C.parse("11011000000000000"), { aset12: true, deductAA: true, bangwang: false, climb: true, nocheck: true }); // 位长异常 → 兜底(位长 < 5 时整体按 '00000') t.eq('位长 6("101010",前 5 位 = "10101" → 12局+房主+傍王+不查)', C.parse("101010"), { aset12: true, deductAA: false, bangwang: true, climb: false, nocheck: true }); t.eq('位长 4("0000",位长不足)→ 兜底', C.parse("0000"), { aset12: false, deductAA: false, bangwang: false, climb: false, nocheck: false }); t.eq('位长 0(空串)→ 兜底', C.parse(""), { aset12: false, deductAA: false, bangwang: false, climb: false, nocheck: false }); // 扩展位允许非 '0'(服务端不校验扩展位内容,由专门读扩展位的代码解释) t.eq('扩展位含 1 不影响协议位解析', C.parse("11011111111"), { aset12: true, deductAA: true, bangwang: false, climb: true, nocheck: true }); // RESERVE_LEN = 6(前后端 SSOT,仅作 SSOT 标记与未来断言使用) t.eq('RESERVE_LEN = 6(前后端 SSOT)', C.RESERVE_LEN, 6); // --- 局数 --- t.eq('6局 "0"', asetcount("00000"), 6); t.eq('12局 "1"', asetcount("10000"), 12); // --- 开房房卡 (design §10.1) --- t.eq('房主6局', needroomcard("00000"), 2); t.eq('房主12局', needroomcard("10000"), 4); t.eq('AA6局', needroomcard("01000"), 1); t.eq('AA12局', needroomcard("11000"), 2); // --- 直接调用 export 的接口(替代复刻映射) --- const exp = require('../class.export.js').new(); t.eq('export 局数6', exp.get_asetcount("00000"), 6); t.eq('export 局数12', exp.get_asetcount("10000"), 12); t.eq('export 房主6局2张', exp.get_needroomcard("00000"), 2); t.eq('export 房主12局4张', exp.get_needroomcard("10000"), 4); t.eq('export AA6局1张', exp.get_needroomcard("01000"), 1); t.eq('export 加入·房主0张', exp.get_needroomcard_joinroom("00000"), 0); t.eq('export 加入·AA6局1张', exp.get_needroomcard_joinroom("01000"), 1); process.exit(t.done('config') ? 0 : 1);