@ginstone/nga-api
Version:
124 lines (123 loc) • 3.98 kB
JavaScript
;
//随机数计算相关工具方法
Object.defineProperty(exports, "__esModule", { value: true });
exports.DiceUtils = void 0;
const BbsTag_1 = require("./BbsTag");
const TagName_1 = require("./TagName");
// 算式正则
const pattern = /(\d*)d(\d+)/;
class DiceUtils {
/**
* 找出所有的dice标签
* @param nodes 节点数组
* @param inCollapse 当前节点是否在 collapse 折叠块中
*/
static findAllDice(nodes, inCollapse) {
if (!nodes) {
return [];
}
// dice列表
const res = new Array;
for (const node of nodes) {
if (node.name === TagName_1.TagName.dice) {
//如果子节点是dice,加入列表
node.inCollapse = !!inCollapse;
res.push(node);
}
else {
// 否则继续到子节点中查询
const cNodes = DiceUtils.findAllDice(node.children, inCollapse || node.name === TagName_1.TagName.collapse);
res.push(...cNodes);
}
}
return res;
}
/**
* 排序
* @param nodes
*/
static sort(nodes) {
if (!nodes) {
return [];
}
const inner = nodes.filter(i => i.inCollapse);
const outer = nodes.filter(i => !i.inCollapse);
return [...outer, ...inner];
}
/**
* 计算
* @param nodes 节点列表
* @param initialSeed 初始种子
*/
static calculate(nodes, initialSeed) {
if (!nodes) {
return;
}
// 找出所有的dice标签
const diceArray = DiceUtils.findAllDice(nodes);
// 按照 collapse外 > collapse内排序
const sortedArray = DiceUtils.sort(diceArray);
//计算每一个dice的随机结果
const allInCollapse = sortedArray[0] && sortedArray[0].inCollapse;
// 初始化种子 , 如果所有dice都在collapse中 种子+1
let seed = initialSeed + (allInCollapse ? 1 : 0);
for (const dice of sortedArray) {
seed = DiceUtils.calculateDice(dice, seed);
}
}
/**
* 根据种子计算一个新种子和结果
* @param seed 种子
*/
static rnd(seed) {
// 计算一个新种子
seed = (seed * 9301 + 49297) % 233280;
// 返回一个结果
return { seed, result: seed / 233280.0 };
}
/**
* 计算一个dice标签的结果,返回种子
* @param dice dice标签
* @param seed 种子
*/
static calculateDice(dice, seed) {
if (!dice || !dice.children || !dice.children[0]) {
return seed;
}
// 总算式
const text = dice.children[0].raw;
// 总结果
let sum = 0;
// 算式分组计算结果
const result = text.split('+').flatMap(t => {
const match = pattern.exec(t);
if (match) {
const count = parseInt(match[1] ? match[1] : "1");
const range = parseInt(match[2]);
const arr = [];
for (let i = 0; i < count; i++) {
// 计算一次
const res = DiceUtils.rnd(seed);
seed = res.seed;
const r = Math.floor(res.result * range + 1);
sum += r;
arr.push(`${t}(${r})`);
}
return arr;
}
else if (!isNaN(Number(t))) {
// 是纯数字
const number = Number(t);
sum += number;
return [number + ''];
}
else {
return ['格式错误'];
}
}).join(" + ");
// 添加分组计算结果
dice.children.push(new BbsTag_1.BbsTag(TagName_1.TagName.text, " = " + result + " = " + sum));
return seed;
}
}
exports.DiceUtils = DiceUtils;