78 lines
3.8 KiB
JavaScript
78 lines
3.8 KiB
JavaScript
///////////////////////////////////////////////////
|
||
////// cls_youle_erqiwang_config: 房间配置解析 //////
|
||
///////////////////////////////////////////////////
|
||
//
|
||
// roomtype 采用定长数字位串(字符串),每一位对应一个开关,'0'/'1',方便前端逐项勾选:
|
||
// 位0 局数: '0'→6局 '1'→12局
|
||
// 位1 扣卡方式: '0'→房主扣卡 '1'→AA每人扣卡
|
||
// 位2 傍王: '0'→关 '1'→开
|
||
// 位3 爬坡: '0'→常规算子 '1'→爬坡
|
||
// 位4 查牌: '0'→可查牌 '1'→不查牌
|
||
// 示例 "10100" = 12局 / 房主扣卡 / 傍王开 / 常规算子 / 可查牌
|
||
// 缺省 "00000" = 6局 / 房主扣卡 / 无傍王 / 常规算子 / 可查牌(对齐 design 缺省)
|
||
//
|
||
// 【位长协议 · 2026-09-01 升级 · 第 2 版】
|
||
// 字串格式 = 「5 位协议位」+「N 位扩展位(默认 N=6,当前全 '0')」
|
||
// 例:'11011' + '000000' = '11011000000'
|
||
// 协议位的位索引(IDX_* = 0..4)永远对应字串前 5 位 charAt(0..4),
|
||
// 在所有版本中不变——这是服务端与子游戏的 SSOT(沿用未升级前的约定)。
|
||
// 扩展位在协议位之后(字串末尾),用于将来加新协议项时向后追加,
|
||
// 旧客户端/旧服务端都按 charAt(0..4) 读协议位(向后兼容)。
|
||
//
|
||
// 兼容策略:parse() / bit() 接受任意长度:
|
||
// - 长度 ≥ 5:bit(idx) 读 charAt(idx),charAt 越界返回 false(等同缺省)
|
||
// - 长度 < 5 / 非字符串:parse() 整体按 '00000' 兜底
|
||
// 不再校验扩展位内容:当前扩展位全 '0' 是惯例,将来版本可能填非 0,
|
||
// 服务端只读协议位 0..4,扩展位由专门读扩展位的代码(如果有)去解释。
|
||
//
|
||
// 本模块是 roomtype 位串格式的唯一解析入口(SSOT);游戏逻辑一律经 parse() 读取,
|
||
// 不得在别处按下标硬解析。
|
||
//
|
||
var cls_youle_erqiwang_config = cls_youle_erqiwang_config || {
|
||
|
||
//位索引常量
|
||
IDX_ASET: 0, //局数
|
||
IDX_DEDUCT: 1, //扣卡方式
|
||
IDX_BANGWANG:2, //傍王
|
||
IDX_CLIMB: 3, //爬坡
|
||
IDX_NOCHECK: 4, //查牌
|
||
|
||
//预留扩展位长度(字串末尾,当前全 '0')。
|
||
//将来加新协议项时,扩展位长不变、协议位索引不变(永远 0..4),
|
||
//扩展位长可以动态增加(任何位置 [5, 5+N) 都行),与旧版兼容。
|
||
//本常量仅作 SSOT 标记与未来断言使用,不影响 parse() / bit() 行为。
|
||
RESERVE_LEN: 6,
|
||
|
||
//取第 idx 位是否为 '1';roomtype 缺失/过短一律按 '0'(缺省)处理
|
||
bit: function(roomtype, idx){
|
||
if (!roomtype || typeof roomtype != "string"){
|
||
return false;
|
||
}
|
||
if (idx < 0 || idx >= roomtype.length){
|
||
return false;
|
||
}
|
||
return roomtype.charAt(idx) == "1";
|
||
},
|
||
|
||
//解析 roomtype 位串为具名配置对象
|
||
//协议位 charAt(0..4) = IDX_ASET..IDX_NOCHECK;扩展位(如果有)由调用方另读
|
||
parse: function(roomtype){
|
||
// 防御式:非字符串 / 过短 → 整体按全 '0' 处理
|
||
if (!roomtype || typeof roomtype != "string" || roomtype.length < 5){
|
||
roomtype = "00000";
|
||
}
|
||
var cfg = {};
|
||
cfg.aset12 = cls_youle_erqiwang_config.bit(roomtype, cls_youle_erqiwang_config.IDX_ASET); //true=12局 false=6局
|
||
cfg.deductAA = cls_youle_erqiwang_config.bit(roomtype, cls_youle_erqiwang_config.IDX_DEDUCT); //true=AA每人 false=房主
|
||
cfg.bangwang = cls_youle_erqiwang_config.bit(roomtype, cls_youle_erqiwang_config.IDX_BANGWANG);//true=开傍王
|
||
cfg.climb = cls_youle_erqiwang_config.bit(roomtype, cls_youle_erqiwang_config.IDX_CLIMB); //true=常规算子
|
||
cfg.nocheck = cls_youle_erqiwang_config.bit(roomtype, cls_youle_erqiwang_config.IDX_NOCHECK); //true=不查牌
|
||
return cfg;
|
||
}
|
||
}
|
||
|
||
//Node(本地/单元测试)导出;友乐/浏览器无 module 时跳过,按全局名引用(dev-guide 01 §1)
|
||
if (typeof module !== "undefined"){
|
||
module.exports = cls_youle_erqiwang_config;
|
||
}
|