UNPKG

@randsum/dice

Version:

A flexible, type-safe dice roller for tabletop RPGs, game development, and probability simulations

2 lines (1 loc) 5.68 kB
var u=require("node:module");var{defineProperty:I,getOwnPropertyNames:y,getOwnPropertyDescriptor:f}=Object,m=Object.prototype.hasOwnProperty;var G=new WeakMap,n=(R)=>{var A=G.get(R),N;if(A)return A;if(A=I({},"__esModule",{value:!0}),R&&typeof R==="object"||typeof R==="function")y(R).map((K)=>!m.call(A,K)&&I(A,K,{get:()=>R[K],enumerable:!(N=f(R,K))||N.enumerable}));return G.set(R,A),A};var c=(R,A)=>{for(var N in A)I(R,N,{get:A[N],enumerable:!0,configurable:!0,set:(K)=>A[N]=()=>K})};var s={};c(s,{roll:()=>F,fudgeDice:()=>h,coin:()=>q,alphaNumDie:()=>P,D8:()=>k,D6:()=>D,D4:()=>T,D20:()=>b,D12:()=>S,D100:()=>B,D10:()=>g,D:()=>x});module.exports=n(s);function Y(R,A=0){if(R.every((N)=>typeof N==="number"))return R.reduce((N,K)=>N+K,A);return R.flat().join(", ")}function $(R){return Math.random()*R|0}var M=new Map;function z(R){let A=Number(R);if(M.has(A)){let K=M.get(A);if(K===void 0)throw new Error("Faces cache is empty");return K}let N=Array.from({length:A},(K,C)=>C+1);if(A<=100||[4,6,8,10,12,20,100].includes(A))M.set(A,N);return N}function _(R,A,N){let K=N??z(A),C=new Array(R);for(let H=0;H<R;H++){let L=$(A),Q=K[L];if(Q)C[H]=Q}return C}function O(){return Math.random().toString(36).substring(2,15)}var t=require("@randsum/core"),Z=require("@randsum/notation");function v(R){return R instanceof x}function U(R){let A=V(R);return{argument:R,options:A,die:o(R),notation:t.optionsConverter.toNotation(A),description:t.optionsConverter.toDescription(A)}}function V(R){if(R instanceof x)return R.toOptions;if(Z.isDiceNotation(R)){let N=(R.match(Z.coreNotationPattern)??"")[0],K=R.replace(N,""),[C,H=""]=N.split(/[Dd]/);if(H.includes("{"))return{quantity:Number(C),sides:[...H.replaceAll(/{|}/g,"")]};return{quantity:Number(C),sides:Number(H),...{modifiers:{...t.DropModifier.parse(K),...t.ExplodeModifier.parse(K),...t.UniqueModifier.parse(K),...t.ReplaceModifier.parse(K),...t.RerollModifier.parse(K),...t.CapModifier.parse(K),...t.PlusModifier.parse(K),...t.MinusModifier.parse(K)}}}}if(Array.isArray(R))return{quantity:1,sides:R.map(String)};if(typeof R==="string"||typeof R==="number")return{quantity:1,sides:Number(R)};return R}function o(R){if(v(R))return R;let A=V(R);return new x(A.sides)}var J=require("@randsum/core");function w(R){return typeof R.sides==="number"}function p(R){let A=r(R.dicePools),N=d(R,A),K=Object.values(N);return{...R,rawRolls:A,modifiedRolls:N,rawResult:Object.values(A).flat(),result:K.map((C)=>C.rolls).flat(),type:i(R.dicePools),total:Y(K.map((C)=>C.total))}}function i(R){let A=Object.values(R);if(A.every((N)=>typeof N.options.sides==="number"))return"numerical";if(A.every((N)=>Array.isArray(N.options.sides)))return"custom";return"mixed"}function l(R){return Array.isArray(R.options.sides)}function X(R,A,N,K){let C=A[R];if(C===void 0)return N;switch(R){case"plus":return{...N,simpleMathModifier:C};case"minus":return{...N,simpleMathModifier:-C};case"reroll":return new J.RerollModifier(A.reroll).apply(N,void 0,K.rollOne);case"unique":return new J.UniqueModifier(A.unique).apply(N,{sides:K.sides,quantity:K.quantity},K.rollOne);case"replace":return new J.ReplaceModifier(A.replace).apply(N);case"cap":return new J.CapModifier(A.cap).apply(N);case"drop":return new J.DropModifier(A.drop).apply(N);case"explode":return new J.ExplodeModifier(A.explode).apply(N,{sides:K.sides,quantity:K.quantity},K.rollOne);default:throw new Error(`Unknown modifier: ${String(R)}`)}}function d(R,A){let N={};for(let[K,C]of Object.entries(R.dicePools)){let H=A[K]??[];if(l(C)){N[K]={total:Y(H),rolls:H};continue}let{sides:L,quantity:Q=1,modifiers:E={}}=C.options;if(Object.keys(E).length===0){N[K]={total:Y(H),rolls:H};continue}let W=()=>$(L),j={simpleMathModifier:0,rolls:H};if(E.reroll)j=X("reroll",E,j,{sides:L,quantity:Q,rollOne:W});if(E.replace)j=X("replace",E,j,{sides:L,quantity:Q,rollOne:W});if(E.cap)j=X("cap",E,j,{sides:L,quantity:Q,rollOne:W});if(E.explode)j=X("explode",E,j,{sides:L,quantity:Q,rollOne:W});if(E.unique)j=X("unique",E,j,{sides:L,quantity:Q,rollOne:W});if(E.drop)j=X("drop",E,j,{sides:L,quantity:Q,rollOne:W});if(E.plus)j=X("plus",E,j,{sides:L,quantity:Q,rollOne:W});if(E.minus)j=X("minus",E,j,{sides:L,quantity:Q,rollOne:W});N[K]={rolls:j.rolls,total:Y(j.rolls,j.simpleMathModifier)}}return N}function r(R){let A={};for(let[N,K]of Object.entries(R)){let{options:C}=K,H=C.quantity??1;if(w(C))A[N]=_(H,C.sides);else A[N]=_(H,C.sides.length,C.sides)}return A}function F(...R){let A={dicePools:Object.fromEntries(R.map((N)=>[O(),U(N)]))};return p(A)}class x{sides;faces;type;isCustom;constructor(R){if(typeof R==="number"){if(!Number.isInteger(R)||R<1)throw new Error("Die must have at least one side with a positive integer value");this.sides=R,this.faces=z(R),this.type="numerical",this.isCustom=!1}else{if(!R.length)throw new Error("Custom die must have at least one face");this.sides=R.length,this.faces=[...R],this.type="custom",this.isCustom=!0}}roll(R=1){let A=this.rollSpread(R);if(this.type==="numerical")return A.reduce((N,K)=>N+K,0);return A.join(", ")}rollSpread(R=1){return _(R,this.sides,this.faces)}rollModified(R=1,A={}){return F({...this.toOptions,quantity:R,modifiers:A})}get toOptions(){if(this.type==="numerical")return{quantity:1,sides:this.sides};return{quantity:1,sides:[...this.faces]}}}var T=new x(4),D=new x(6),k=new x(8),g=new x(10),S=new x(12),b=new x(20),B=new x(100),q=new x(["Heads","Tails"]),h=new x(["+","+","+","-"," "," "]),a=["A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","0","1","2","3","4","5","6","7","8","9"],P=new x(a);