@randsum/dice
Version:
A flexible, type-safe dice roller
2 lines (1 loc) • 4.52 kB
JavaScript
function p(t,n=0){if(t.every((m)=>typeof m==="number"))return t.reduce((m,R)=>m+R,n);return t.flat().join(", ")}function x(t){return Math.floor(Math.random()*t)}function r(t){return Array.from({length:Number(t)},(n,m)=>m+1)}function b(t,n,m){let R=m??r(n);return Array.from({length:t},()=>x(n)).map((N)=>{return R[N]})}function F(){return Math.random().toString(36).substring(2,15)}import{CapModifier as Q,DropModifier as S,ExplodeModifier as W,MinusModifier as X,PlusModifier as Y,ReplaceModifier as $,RerollModifier as G,UniqueModifier as Z,optionsConverter as K}from"@randsum/core";import{coreNotationPattern as g,isDiceNotation as I}from"@randsum/notation";function E(t){return t instanceof A}function C(t){let n=_(t);return{argument:t,options:n,die:U(t),notation:K.toNotation(n),description:K.toDescription(n)}}function _(t){if(t instanceof A)return t.toOptions;if(I(t)){let m=(t.match(g)??"")[0],R=t.replace(m,""),[N,u=""]=m.split(/[Dd]/);if(u.includes("{"))return{quantity:Number(N),sides:[...u.replaceAll(/{|}/g,"")]};return{quantity:Number(N),sides:Number(u),...{modifiers:{...S.parse(R),...W.parse(R),...Z.parse(R),...$.parse(R),...G.parse(R),...Q.parse(R),...Y.parse(R),...X.parse(R)}}}}if(Array.isArray(t))return{quantity:1,sides:t.map(String)};if(typeof t==="string"||typeof t==="number")return{quantity:1,sides:Number(t)};return t}function U(t){if(E(t))return t;let n=_(t);return new A(n.sides)}import{CapModifier as V,DropModifier as D,ExplodeModifier as T,MinusModifier as h,PlusModifier as q,ReplaceModifier as y,RerollModifier as w,UniqueModifier as c}from"@randsum/core";function j(t){return typeof t.sides==="number"}function M(t){let n=i(t.dicePools),m=e(t,n),R=Object.values(m);return{...t,rawRolls:n,modifiedRolls:m,rawResult:Object.values(n).flat(),result:R.map((N)=>N.rolls).flat(),type:k(t.dicePools),total:p(R.map((N)=>N.total))}}function k(t){let n=Object.values(t);if(n.every((m)=>typeof m.options.sides==="number"))return"numerical";if(n.every((m)=>Array.isArray(m.options.sides)))return"custom";return"mixed"}function B(t){return Array.isArray(t.options.sides)}function P(t,n,m,R){let u={reroll:()=>new w(n.reroll).apply(m,void 0,R.rollOne),unique:()=>new c(n.unique).apply(m,{sides:R.sides,quantity:R.quantity},R.rollOne),replace:()=>new y(n.replace).apply(m),cap:()=>new V(n.cap).apply(m),drop:()=>new D(n.drop).apply(m),explode:()=>new T(n.explode).apply(m,{sides:R.sides,quantity:R.quantity},R.rollOne),plus:()=>new q(n.plus).apply(m),minus:()=>new h(n.minus).apply(m)}[t];if(!u)throw new Error(`Unknown modifier: ${t}`);return u()}function e(t,n){return Object.fromEntries(Object.entries(t.dicePools).map(([m,R])=>{let N=n[m]??[];if(B(R))return[m,{total:p(N),rolls:N}];let{options:{sides:u,quantity:v=1,modifiers:z={}}}=R,H=()=>x(u),f=Object.keys(z).reduce((J,L)=>P(L,z,J,{sides:u,quantity:v,rollOne:H}),{simpleMathModifier:0,rolls:N});return[m,{rolls:f.rolls,total:p(f.rolls,f.simpleMathModifier)}]}))}function i(t){return Object.fromEntries(Object.entries(t).map(([n,m])=>{let{options:R}=m,N=R.quantity??1;if(j(R))return[n,b(N,R.sides)];return[n,b(N,R.sides.length,R.sides)]}))}function O(...t){let n={dicePools:Object.fromEntries(t.map((m)=>[F(),C(m)]))};return M(n)}class A{sides;faces;type;isCustom;constructor(t){if(typeof t==="number"){if(!Number.isInteger(t)||t<1)throw new Error("Die must have at least one side with a positive integer value");this.sides=t,this.faces=r(t),this.type="numerical",this.isCustom=!1}else{if(!t.length)throw new Error("Custom die must have at least one face");this.sides=t.length,this.faces=[...t],this.type="custom",this.isCustom=!0}}roll(t=1){let n=this.rollSpread(t);if(this.type==="numerical")return n.reduce((m,R)=>m+R,0);return n.join(", ")}rollSpread(t=1){return b(t,this.sides,this.faces)}rollModified(t=1,n={}){return O({...this.toOptions,quantity:t,modifiers:n})}get toOptions(){if(this.type==="numerical")return{quantity:1,sides:this.sides};return{quantity:1,sides:[...this.faces]}}}var o=new A(4),l=new A(6),d=new A(8),a=new A(10),s=new A(12),tt=new A(20),nt=new A(100),mt=new A(["Heads","Tails"]),Rt=new A(["+","+","+","-"," "," "]),At=["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"],Nt=new A(At);export{O as roll,Rt as fudgeDice,mt as coin,Nt as alphaNumDie,d as D8,l as D6,o as D4,tt as D20,s as D12,nt as D100,a as D10,A as D};