UNPKG

@ginstone/nga-api

Version:

124 lines (123 loc) 3.98 kB
"use strict"; //随机数计算相关工具方法 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;