/////////////////////////////////////////////////////////////// ////////// EQW_GameState: 服务端快照的镜像(前端 SSOT)//////// /////////////////////////////////////////////////////////////// // 前端红线「视图 = f(服务端快照)」的落点:本对象只存【服务端下发过的字段】, // 不存任何前端算出来的结论。手牌排序、牌面标记、花色统计等由 core/ 的纯函数 // 在渲染时现算,不落地成状态。 // // 三条硬约束: // 1. 只镜像不派生——存进来的必须是服务端给过的 // 2. 字段名对齐协议——协议叫 currcall 就叫 currcall,便于逐条核对 // 3. 缺字段不兜底——包里没有的保持原值,不填默认值掩盖;必需字段缺失 // 则 console.error 并跳过该包(服务端漏发,修在服务端) var EQW_GameState = EQW_GameState || { //数据分组名(snapshot / reset 按此遍历;新增分组要同步加进来) _GROUPS: ['room', 'aset', 'turn', 'call', 'my', 'table', 'result'], //—— 房间级(跨小局)—— room: { asetCount: 0, //总局数 ← fapai.asetcount / deskinfo.count / setRoomDes asetIdx: 0, //当前第几局 ← fapai.asetidx / deskinfo.idx mySeat: -1, //自己的座位 ← 平台 C_Player.seat playerScores: [], //三家总积分 ← deskinfo.PlayerInfo options: null //roomtype 解析结果 }, //—— 小局级 —— aset: { step: 0, //1叫分 2选主/投降 3埋牌 5出牌 6结算 banker: -1, call: -1, //庄家叫分 multiple: 0, //基础子数 flower: 0, //主牌花色(0 = 未选主) curmultiple: 0, //当前抓分倍数(带符号,服务端权威,前端不自算) grade: 0, //闲家已捡分 baozhu: 0, //是否已有人报无主 touxiang: 0 //是否允许投降 }, //—— 当前控制权与倒计时(任何阶段都读这里)—— turn: { seat: -1, //该谁操作 countdown: 0 //展示用秒数;服务端无对应定时器,归零【不做任何界面推进】 }, //—— 叫分过程 —— call: { currcall: 0, calls: [null, null, null] //null 未叫 / 0 不叫 / >0 叫了多少 }, //—— 自己 —— my: { cards: [], mustCard: [], //本轮必出牌(服务端建议,只发给轮到的那家) bottomCards: [], //底牌(庄家恒有;闲家仅 70 分坐庄时有) buryCards: [] //埋牌底牌(仅庄家) }, //—— 桌面 —— table: { ancard3s: 0, //开底标志(70 分坐庄) playproc: null, pushlist: [], seatlist: [], liangpai: null, mingpai: null }, //—— 结算 —— result: { chupai: null, bottom: null, aset: null, account: null }, //新一局开局时清空对局态;room.mySeat 与 room.options 跨局不变,不清 reset: function () { this.room.asetIdx = 0; this.room.playerScores = []; this.aset = { step: 0, banker: -1, call: -1, multiple: 0, flower: 0, curmultiple: 0, grade: 0, baozhu: 0, touxiang: 0 }; this.turn = { seat: -1, countdown: 0 }; this.call = { currcall: 0, calls: [null, null, null] }; this.my = { cards: [], mustCard: [], bottomCards: [], buryCards: [] }; this.table = { ancard3s: 0, playproc: null, pushlist: [], seatlist: [], liangpai: null, mingpai: null }; this.result = { chupai: null, bottom: null, aset: null, account: null }; }, //深拷贝快照(只含数据分组,不含方法),供测试做「增量 vs 全量」比对 snapshot: function () { var out = {}; for (var i = 0; i < this._GROUPS.length; i++) { var g = this._GROUPS[i]; out[g] = JSON.parse(JSON.stringify(this[g])); } return out; } };