- test/_shim.js:平台全局垫片(min_ary_include/deduct、min_random/now/ontimeout、 youle_erqiwang.import mock),忠实复刻 minhttp.js;仅测试用,不进正式代码 - test/_assert.js + run.js:极简断言与总运行器 - test/test_arith.js(扣底/算子常规+爬坡/算奖/甩牌/跟牌分量) test_config.js(位串/局数扣卡) test/test_paiju.js(亮牌/结算 get_paiju_account 集成),共 89 项断言全过 - test/README.md:运行方式与双运行时原理 - CLAUDE.md:常用命令补测试入口,说明服务端双运行时规范 (CLAUDE.md 内另含此前一处措辞微调,随本次文档更新一并纳入) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
54 lines
2.9 KiB
JavaScript
54 lines
2.9 KiB
JavaScript
// paiju 单测:亮牌(§8.2) + 结算 get_paiju_account(§7/§8) 集成
|
|
require('./_shim');
|
|
const P = require('../class.paiju.js');
|
|
const t = require('./_assert')();
|
|
|
|
const id = (d, f, n) => (d - 1) * 54 + (f - 1) * 13 + (n - 1);
|
|
const big = d => (d - 1) * 54 + 53;
|
|
const small = d => (d - 1) * 54 + 52;
|
|
|
|
// ============ §8.2 亮牌 get_liangpai ============
|
|
// 构造庄家(seat0)手牌 o_paiju;副花色中性单张填充到28
|
|
function fill(req, n) {
|
|
const u = new Set(req), o = req.slice();
|
|
for (const f of [2, 3, 4]) for (const x of [1, 5, 6, 8, 9, 10, 11, 12, 13]) {
|
|
if (o.length >= n) break;
|
|
const c = id(1, f, x);
|
|
if (!u.has(c)) { u.add(c); o.push(c); }
|
|
}
|
|
return o;
|
|
}
|
|
const mkHand = ids => ({ flower: 1, banker: 0, cards: ids.map(x => ({ id: x, playround: -1, dealowner: 1 })) });
|
|
const lp = ids => P.get_liangpai(mkHand(fill(ids, 28)));
|
|
t.eq('亮牌 3王', lp([big(1), small(1), small(2)]), { wang: 3 });
|
|
t.eq('亮牌 4王+6个7(固定主10)', lp([big(1), big(2), small(1), small(2), id(1, 1, 7), id(2, 1, 7), id(1, 2, 7), id(2, 2, 7), id(1, 3, 7), id(2, 3, 7)]), { zhu: 10, zhupair: 5, zhutuo: 1, wang: 4, qi: 6 });
|
|
t.eq('亮牌 6个2', lp([id(1, 1, 2), id(2, 1, 2), id(1, 2, 2), id(2, 2, 2), id(1, 3, 2), id(2, 3, 2)]), { er: 6 });
|
|
t.eq('亮牌 2王2个7(不达标)', lp([big(1), small(1), id(1, 1, 7), id(2, 1, 7)]), null);
|
|
|
|
// ============ §7/§8 结算 get_paiju_account 集成 ============
|
|
// 最小 o_paiju/o_desk/o_room:控制捡分与手牌,验证最终 seatlist 各家 grade
|
|
function mkPaiju(call, flower, cards, roomtype) {
|
|
const o_desk = {
|
|
seatlist: [[0, []], [0, []], [0, []]],
|
|
o_room: { roomtype: roomtype, asetcount: 6 },
|
|
method: { get_desk_account: msg => msg }
|
|
};
|
|
return { call, banker: 0, flower, cards, idx: 2, o_desk, endtime: null, result: null };
|
|
}
|
|
// 闲家1(seat1) 赢两张K(各10分)=捡分20;庄家(seat0)仅1张手牌(不足28→无算奖)
|
|
const cards = [
|
|
{ id: 0, dealowner: 2, playround: 1, playowner: 1, score: 10, number: 13, flower: 1 },
|
|
{ id: 1, dealowner: 3, playround: 1, playowner: 1, score: 10, number: 13, flower: 1 },
|
|
{ id: 2, dealowner: 1, playround: -1, playowner: -1, score: 0, number: 5, flower: 1 }
|
|
];
|
|
// 常规 65 分、捡分20 → 小光(×2)、基础2 → X=4:庄+8、闲各 -4
|
|
let msg = P.get_paiju_account(mkPaiju(65, 1, cards, "00000"), 0, {});
|
|
t.eq('结算 65小光 grade', msg.data.aset.seatlist.map(p => p.grade), [8, -4, -4]);
|
|
t.eq('结算 65小光 upgrade/multiple', [msg.data.aset.upgrade, msg.data.aset.multiple], [2, 2]);
|
|
// 投降(type1):基础1、X=1、庄输1子/闲 → 庄-2、闲各 +1
|
|
let msg2 = P.get_paiju_account(mkPaiju(70, -1, cards, "00000"), 1, {});
|
|
t.eq('结算 投降 grade', msg2.data.aset.seatlist.map(p => p.grade), [-2, 1, 1]);
|
|
t.eq('结算 投降 upgrade(标识)', msg2.data.aset.upgrade, -99);
|
|
|
|
process.exit(t.done('paiju') ? 0 : 1);
|