diff --git a/server/games/erqiwang/class.paiju.js b/server/games/erqiwang/class.paiju.js index 284b2ad..dba0c8b 100644 --- a/server/games/erqiwang/class.paiju.js +++ b/server/games/erqiwang/class.paiju.js @@ -638,6 +638,11 @@ var cls_youle_erqiwang_paiju = cls_youle_erqiwang_paiju || { re1.cardtype = can.cardtype; re1.cards = cards; //实际打出的牌(甩错时为单张) re1.shuaicuo = _shuaicuo; + //合法甩牌的分量构成:cardtype 只能表达单一牌型,甩牌(单张/对子/拖拉机自由混搭, + //design §5.4.3)会被压平成 1xx/2xx,客户端无从据此还原分组,故另行下发分量需求 + if (o_paiju.playproc.shuai_demand){ + re1.shuai = o_paiju.playproc.shuai_demand; + } return re1; } diff --git a/server/games/erqiwang/mod.js b/server/games/erqiwang/mod.js index ab51fc3..bb349d6 100644 --- a/server/games/erqiwang/mod.js +++ b/server/games/erqiwang/mod.js @@ -477,6 +477,11 @@ youle_erqiwang.chupai = function(pack){ msg.data.count = re.count; msg.data.flower = re.flower; msg.data.cardtype = re.cardtype; + //合法甩牌的分量构成(design §5.4.3),供前端按 拖拉机/对子/单张 分组展示; + //非甩牌(含甩错退化为单张)无此属性 + if (re.shuai){ + msg.data.shuai = re.shuai; + } break; case 2: //第二个出牌 msg.rpc = "chupai2"; diff --git a/server/games/erqiwang/test/test_rpc.js b/server/games/erqiwang/test/test_rpc.js index 0db7345..3f8eed0 100644 --- a/server/games/erqiwang/test/test_rpc.js +++ b/server/games/erqiwang/test/test_rpc.js @@ -133,6 +133,51 @@ t.eq('埋牌 不查牌 闲家无liangpai', mpXian && mpXian.data.liangpai, undef t.eq('重连 可查牌 PushCards有seatlist', E.get_deskinfo(e.o_room, 1).PushCards.seatlist !== undefined, true); t.eq('重连 不查牌 PushCards无seatlist', E.get_deskinfo(en.o_room, 1).PushCards.seatlist, undefined); +// ===================== §5.4 甩牌:chupai1 需下发分量构成 shuai(cardtype 表达不了甩牌)===================== +// 主花色=♦(1)。庄家(0) 甩「主♦K对 + 主♦5单张」;两闲家手上一张主牌都没有 → 甩牌合法 +function mkShuai(extraToSeat1) { + const pj = { + idx: 1, step: 5, banker: 0, call: 65, flower: 1, callproc: [], + seatlist: [[[0, 0], [0, 0], [0, 0], [0, 0], [-1, -1]], [[0, 0], [0, 0], [0, 0], [0, 0], [-1, -1]], [[0, 0], [0, 0], [0, 0], [0, 0], [-1, -1]]], + playproc: {}, cards: make108() + }; + for (let i = 0; i < 108; i++) pj.cards[i].dealowner = -1; // 先全部清空 + const give = (cid, s) => { pj.cards[cid].dealowner = s + 1; pj.cards[cid].playround = -1; }; + give(id(1, 1, 13), 0); give(id(2, 1, 13), 0); give(id(1, 1, 5), 0); // 庄家:主♦K对 + 主♦5 + give(id(1, 3, 9), 1); give(id(1, 3, 8), 1); give(id(2, 3, 9), 1); // 闲1:全副♥,无主牌 + give(id(1, 2, 9), 2); give(id(1, 2, 8), 2); give(id(2, 2, 9), 2); // 闲2:全副♣,无主牌 + if (extraToSeat1) give(extraToSeat1, 1); // 需要造甩错时给闲1一张大主牌 + pj.method = { + check_cards_valid: c => P.check_cards_valid(pj, c), + check_cards_inhand: (c, s) => P.check_cards_inhand(pj, c, s), + do_playcard: c => P.do_playcard(pj, c), + get_seat_cards: s => P.get_seat_cards(pj, s), + have_baofu: () => (pj.seatlist[0][4][0] == 0 || pj.seatlist[1][4][0] == 0 || pj.seatlist[2][4][0] == 0) + }; + P.new_playround(pj, 1, 0); + return pj; +} +// 合法甩牌 → 带 shuai 分量 +let sh = mkShuai(null); let shc = setup("00000", sh); +mod.chupai(pack(0, { cards: [id(1, 1, 13), id(2, 1, 13), id(1, 1, 5)] })); +let shPk = shc.sent.filter(m => m.rpc === 'chupai1')[0]; +t.eq('甩牌 合法 下发 chupai1', !!shPk, true); +t.eq('甩牌 打出3张', shPk && shPk.data.cards.length, 3); +t.eq('甩牌 shuai=1对+1单张', shPk && shPk.data.shuai, { tractors: [], pairs: 1, singles: 1 }); +t.eq('甩牌 无 shuaicuo', shPk && shPk.data.shuaicuo, undefined); +// 非甩牌(单一对子)→ 无 shuai +sh = mkShuai(null); shc = setup("00000", sh); +mod.chupai(pack(0, { cards: [id(1, 1, 13), id(2, 1, 13)] })); +shPk = shc.sent.filter(m => m.rpc === 'chupai1')[0]; +t.eq('非甩牌(单一对子) 无 shuai', shPk && shPk.data.shuai, undefined); +// 甩错(闲1 持大王,能压过主K对里的单张分量)→ 收回、只打最小一张、无 shuai +sh = mkShuai((2 - 1) * 54 + 53); shc = setup("00000", sh); // 第二副大王给闲1 +mod.chupai(pack(0, { cards: [id(1, 1, 13), id(2, 1, 13), id(1, 1, 5)] })); +shPk = shc.sent.filter(m => m.rpc === 'chupai1')[0]; +t.eq('甩错 shuaicuo=1', shPk && shPk.data.shuaicuo, 1); +t.eq('甩错 只打出最小一张(主♦5)', shPk && shPk.data.cards, [id(1, 1, 5)]); +t.eq('甩错 无 shuai 分量', shPk && shPk.data.shuai, undefined); + // ===================== 重连 PushCards.pushlist:结构恒 3 座位 + 按本局主牌花色排序 ===================== // 造 5 轮已出牌的牌局(每轮每家 1 张),外加 seat0 在第 1 轮同时出「主5 + 副♥A」用于验证排序 function mkPushlist() {