feat: dice roller improved
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
import { tokenize, parse } from "./parser";
|
||||
import { rollDicePool, roll } from "./roller";
|
||||
import type { DicePool } from "./types";
|
||||
|
||||
/**
|
||||
* 骰子引擎测试
|
||||
* 在浏览器控制台运行:window.testDiceEngine()
|
||||
*/
|
||||
|
||||
export function testDiceEngine() {
|
||||
console.log("=== 骰子引擎测试 ===\n");
|
||||
|
||||
// 测试用例
|
||||
const testCases: Array<{
|
||||
name: string;
|
||||
formula: string;
|
||||
expected: {
|
||||
hasPools: number;
|
||||
hasModifier?: boolean;
|
||||
};
|
||||
}> = [
|
||||
{
|
||||
name: "标准骰子 3d6",
|
||||
formula: "3d6",
|
||||
expected: { hasPools: 1 },
|
||||
},
|
||||
{
|
||||
name: "单个骰子 d20",
|
||||
formula: "d20",
|
||||
expected: { hasPools: 1 },
|
||||
},
|
||||
{
|
||||
name: "骰池字面量 {d4,d8}",
|
||||
formula: "{d4,d8}",
|
||||
expected: { hasPools: 1 },
|
||||
},
|
||||
{
|
||||
name: "带修饰符 3d6kh2",
|
||||
formula: "3d6kh2",
|
||||
expected: { hasPools: 1, hasModifier: true },
|
||||
},
|
||||
{
|
||||
name: "带修饰符 4d6dl1",
|
||||
formula: "4d6dl1",
|
||||
expected: { hasPools: 1, hasModifier: true },
|
||||
},
|
||||
{
|
||||
name: "组合骰池 3d6+5",
|
||||
formula: "3d6+5",
|
||||
expected: { hasPools: 2 },
|
||||
},
|
||||
{
|
||||
name: "负数组合 3d6-2",
|
||||
formula: "3d6-2",
|
||||
expected: { hasPools: 2 },
|
||||
},
|
||||
{
|
||||
name: "复杂公式 3d6+{d4,d8}kh2-5",
|
||||
formula: "3d6+{d4,d8}kh2-5",
|
||||
expected: { hasPools: 4, hasModifier: true },
|
||||
},
|
||||
{
|
||||
name: "多个骰池 {d6,d8}+{d10,d12}",
|
||||
formula: "{d6,d8}+{d10,d12}",
|
||||
expected: { hasPools: 2 },
|
||||
},
|
||||
{
|
||||
name: "Keep Lowest 5d6kl3",
|
||||
formula: "5d6kl3",
|
||||
expected: { hasPools: 1, hasModifier: true },
|
||||
},
|
||||
{
|
||||
name: "Drop Highest 4d6dh1",
|
||||
formula: "4d6dh1",
|
||||
expected: { hasPools: 1, hasModifier: true },
|
||||
},
|
||||
];
|
||||
|
||||
let passed = 0;
|
||||
let failed = 0;
|
||||
|
||||
for (const tc of testCases) {
|
||||
try {
|
||||
// 测试词法分析
|
||||
const tokens = tokenize(tc.formula);
|
||||
console.log(`\n公式:${tc.formula}`);
|
||||
console.log(` 令牌:${tokens.length} 个`);
|
||||
|
||||
// 测试语法分析
|
||||
const pools = parse(tokens);
|
||||
console.log(` 骰池:${pools.length} 个`);
|
||||
|
||||
// 测试掷骰
|
||||
const result = roll(tc.formula);
|
||||
console.log(` 结果:${result.total}`);
|
||||
console.log(` 详情:${result.detail}`);
|
||||
|
||||
// 验证
|
||||
if (pools.length >= tc.expected.hasPools) {
|
||||
console.log(` ✓ 通过`);
|
||||
passed++;
|
||||
} else {
|
||||
console.log(` ✗ 失败:期望至少 ${tc.expected.hasPools} 个骰池,实际 ${pools.length} 个`);
|
||||
failed++;
|
||||
}
|
||||
|
||||
if (tc.expected.hasModifier) {
|
||||
const hasMod = pools.some((p) => p.modifier !== undefined);
|
||||
if (hasMod) {
|
||||
console.log(` ✓ 修饰符正确`);
|
||||
} else {
|
||||
console.log(` ✗ 修饰符缺失`);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(` ✗ 错误:${e instanceof Error ? e.message : String(e)}`);
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`\n=== 测试完成:${passed} 通过,${failed} 失败 ===`);
|
||||
return { passed, failed };
|
||||
}
|
||||
|
||||
// 在浏览器环境下暴露到全局
|
||||
if (typeof window !== "undefined") {
|
||||
(window as any).testDiceEngine = testDiceEngine;
|
||||
}
|
||||
Reference in New Issue
Block a user