@allemandi/gacha-engine 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +42 -11
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.module.js +1 -1
- package/dist/index.module.js.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -45,8 +45,8 @@ const pools = [
|
|
|
45
45
|
{
|
|
46
46
|
rarity: 'SSR',
|
|
47
47
|
items: [
|
|
48
|
-
{ name: 'Super Hobo', weight: 0.8, rateUp: true },
|
|
49
|
-
{ name: 'Broke King', weight: 0.4 },
|
|
48
|
+
{ name: 'Super Hobo', weight: 0.8, rateUp: true },
|
|
49
|
+
{ name: 'Broke King', weight: 0.4 },
|
|
50
50
|
{ name: 'Cardboard Hero', weight: 0.4 },
|
|
51
51
|
{ name: 'Newspaper Warmer', weight: 0.4 }
|
|
52
52
|
]
|
|
@@ -54,17 +54,25 @@ const pools = [
|
|
|
54
54
|
{
|
|
55
55
|
rarity: 'SR',
|
|
56
56
|
items: [
|
|
57
|
-
{ name: 'Cold Salaryman', weight: 1.5, rateUp: true },
|
|
58
|
-
{ name: 'Numb Artist', weight: 1.8 },
|
|
57
|
+
{ name: 'Cold Salaryman', weight: 1.5, rateUp: true },
|
|
58
|
+
{ name: 'Numb Artist', weight: 1.8 },
|
|
59
59
|
{ name: 'Crying Cook', weight: 1.8 },
|
|
60
60
|
{ name: 'Lonely Cat', weight: 1.8 }
|
|
61
61
|
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
rarity: 'R',
|
|
65
|
+
items: [
|
|
66
|
+
{ name: 'Regular Joe', weight: 5.0 },
|
|
67
|
+
{ name: 'Normal Person', weight: 5.0 }
|
|
68
|
+
]
|
|
62
69
|
}
|
|
63
70
|
];
|
|
64
71
|
|
|
65
72
|
const rarityRates = {
|
|
66
|
-
SSR: 0.01, // 1% chance for SSR
|
|
67
|
-
SR: 0.
|
|
73
|
+
SSR: 0.01, // 1% chance for SSR
|
|
74
|
+
SR: 0.05, // 5% chance for SR
|
|
75
|
+
R: 0.94 // 94% chance for R
|
|
68
76
|
};
|
|
69
77
|
|
|
70
78
|
const engine = new GachaEngine({ pools, rarityRates });
|
|
@@ -92,14 +100,25 @@ console.log(`Current rate-up items: ${rateUpItems.join(', ')}`);
|
|
|
92
100
|
**CommonJS**
|
|
93
101
|
```js
|
|
94
102
|
const { GachaEngine } = require('@allemandi/gacha-engine');
|
|
103
|
+
|
|
104
|
+
// Same configuration as above
|
|
105
|
+
const engine = new GachaEngine({ pools, rarityRates });
|
|
106
|
+
console.log('Single roll:', engine.roll());
|
|
95
107
|
```
|
|
96
108
|
|
|
97
|
-
**UMD**
|
|
109
|
+
**UMD (Browser)**
|
|
98
110
|
```html
|
|
99
111
|
<script src="https://unpkg.com/@allemandi/gacha-engine"></script>
|
|
100
112
|
<script>
|
|
101
|
-
|
|
102
|
-
|
|
113
|
+
// Access the GachaEngine class
|
|
114
|
+
const { GachaEngine } = window.AllemandiGachaEngine;
|
|
115
|
+
|
|
116
|
+
const engine = new GachaEngine({
|
|
117
|
+
rarityRates: {
|
|
118
|
+
SSR: 0.01,
|
|
119
|
+
SR: 0.05,
|
|
120
|
+
R: 0.94
|
|
121
|
+
},
|
|
103
122
|
pools: [
|
|
104
123
|
{
|
|
105
124
|
rarity: 'SSR',
|
|
@@ -107,12 +126,24 @@ const { GachaEngine } = require('@allemandi/gacha-engine');
|
|
|
107
126
|
{ name: 'Park Master', weight: 0.7, rateUp: true },
|
|
108
127
|
{ name: 'Trash Titan', weight: 0.3 }
|
|
109
128
|
]
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
rarity: 'SR',
|
|
132
|
+
items: [
|
|
133
|
+
{ name: 'Street Sweeper', weight: 1.0 }
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
rarity: 'R',
|
|
138
|
+
items: [
|
|
139
|
+
{ name: 'Regular Person', weight: 1.0 }
|
|
140
|
+
]
|
|
110
141
|
}
|
|
111
142
|
]
|
|
112
143
|
});
|
|
113
144
|
|
|
114
145
|
console.log('Single roll:', engine.roll());
|
|
115
|
-
|
|
146
|
+
console.log('Drop rate for Park Master:', engine.getItemDropRate('Park Master'));
|
|
116
147
|
</script>
|
|
117
148
|
```
|
|
118
149
|
|
|
@@ -124,7 +155,7 @@ const { GachaEngine } = require('@allemandi/gacha-engine');
|
|
|
124
155
|
Creates a new GachaEngine instance with validation.
|
|
125
156
|
|
|
126
157
|
**Config Properties:**
|
|
127
|
-
- `rarityRates` **(required)**: Object mapping rarity names to their base probabilities (
|
|
158
|
+
- `rarityRates` **(required)**: Object mapping rarity names to their base probabilities (should sum to ≤ 1.0)
|
|
128
159
|
- `pools` **(required)**: Array of rarity pools, each containing:
|
|
129
160
|
- `rarity`: String identifier matching a key in `rarityRates`
|
|
130
161
|
- `items`: Array of items with:
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function t(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=Array(r);e<r;e++)n[e]=t[e];return n}function r(r,e){var n="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(n)return(n=n.call(r)).next.bind(n);if(Array.isArray(r)||(n=function(r,e){if(r){if("string"==typeof r)return t(r,e);var n={}.toString.call(r).slice(8,-1);return"Object"===n&&r.constructor&&(n=r.constructor.name),"Map"===n||"Set"===n?Array.from(r):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?t(r,e):void 0}}(r))||e&&r&&"number"==typeof r.length){n&&(r=n);var i=0;return function(){return i>=r.length?{done:!0}:{done:!1,value:r[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}exports.GachaEngine=/*#__PURE__*/function(){function t(t){var r=t.rarityRates,e=t.pools;this.pools=void 0,this.rarityRates=void 0,this.dropRateCache=new Map,this.pools=e,this.rarityRates=r,this.validateConfig()}var e=t.prototype;return e.validateConfig=function(){var t=new Set(Object.keys(this.rarityRates)),e=new Set(this.pools.map(function(t){return t.rarity})),n=
|
|
1
|
+
function t(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=Array(r);e<r;e++)n[e]=t[e];return n}function r(r,e){var n="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(n)return(n=n.call(r)).next.bind(n);if(Array.isArray(r)||(n=function(r,e){if(r){if("string"==typeof r)return t(r,e);var n={}.toString.call(r).slice(8,-1);return"Object"===n&&r.constructor&&(n=r.constructor.name),"Map"===n||"Set"===n?Array.from(r):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?t(r,e):void 0}}(r))||e&&r&&"number"==typeof r.length){n&&(r=n);var i=0;return function(){return i>=r.length?{done:!0}:{done:!1,value:r[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}exports.GachaEngine=/*#__PURE__*/function(){function t(t){var r=t.rarityRates,e=t.pools;this.pools=void 0,this.rarityRates=void 0,this.dropRateCache=new Map,this.pools=e,this.rarityRates=r,this.validateConfig()}var e=t.prototype;return e.validateConfig=function(){var t=new Set(Object.keys(this.rarityRates)),e=new Set(this.pools.map(function(t){return t.rarity})),n=Array.from(e).filter(function(r){return!t.has(r)});if(n.length>0)throw new Error("Missing rarity rates for: "+n.join(", "));for(var i,o=r(this.pools);!(i=o()).done;){var a=i.value;if(0===a.items.length)throw new Error('Rarity "'+a.rarity+'" has no items');if(a.items.reduce(function(t,r){return t+r.weight},0)<=0)throw new Error('Rarity "'+a.rarity+'" has zero total weight')}},e.getItemDropRate=function(t){if(this.dropRateCache.has(t))return this.dropRateCache.get(t);for(var e,n=r(this.pools);!(e=n()).done;){var i=e.value,o=i.items.find(function(r){return r.name===t});if(o){var a=i.items.reduce(function(t,r){return t+r.weight},0),s=o.weight/a*this.rarityRates[i.rarity];return this.dropRateCache.set(t,s),s}}throw new Error('Item "'+t+'" not found')},e.getRarityProbability=function(t){if(!this.rarityRates[t])throw new Error('Rarity "'+t+'" not found');return this.rarityRates[t]},e.getCumulativeProbabilityForItem=function(t,r){var e=this.getItemDropRate(t);return 1-Math.pow(1-e,r)},e.getRollsForTargetProbability=function(t,r){var e=this.getItemDropRate(t);return e<=0?Infinity:Math.ceil(Math.log(1-r)/Math.log(1-e))},e.getRateUpItems=function(){return this.pools.flatMap(function(t){return t.items.filter(function(t){return t.rateUp}).map(function(t){return t.name})})},e.getAllItemDropRates=function(){var t=this;return this.pools.flatMap(function(r){return r.items.map(function(e){return{name:e.name,dropRate:t.getItemDropRate(e.name),rarity:r.rarity}})})},e.roll=function(t){var r=this;void 0===t&&(t=1);for(var e=[],n=function(){var t=r.selectRarity(),n=r.pools.find(function(r){return r.rarity===t}),i=r.selectItemFromPool(n);e.push(i.name)},i=0;i<t;i++)n();return e},e.selectRarity=function(){for(var t=Math.random(),r=0,e=0,n=Object.entries(this.rarityRates);e<n.length;e++){var i=n[e];if(t<=(r+=i[1]))return i[0]}return Object.keys(this.rarityRates)[0]},e.selectItemFromPool=function(t){for(var e,n=t.items.reduce(function(t,r){return t+r.weight},0),i=Math.random()*n,o=0,a=r(t.items);!(e=a()).done;){var s=e.value;if(i<=(o+=s.weight))return s}return t.items[0]},t}();
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","sources":["../src/gacha-engine.ts"],"sourcesContent":["import { RarityInput, GachaEngineConfig } from './types';\n\nexport class GachaEngine {\n private pools: RarityInput[];\n private rarityRates: Record<string, number>;\n private dropRateCache = new Map<string, number>();\n\n constructor({ rarityRates, pools }: GachaEngineConfig) {\n this.pools = pools;\n this.rarityRates = rarityRates;\n this.validateConfig();\n }\n\n private validateConfig(): void {\n const configuredRarities = new Set(Object.keys(this.rarityRates));\n const usedRarities = new Set(this.pools.map(p => p.rarity));\n const
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/gacha-engine.ts"],"sourcesContent":["import { RarityInput, GachaEngineConfig } from './types';\n\nexport class GachaEngine {\n private pools: RarityInput[];\n private rarityRates: Record<string, number>;\n private dropRateCache = new Map<string, number>();\n\n constructor({ rarityRates, pools }: GachaEngineConfig) {\n this.pools = pools;\n this.rarityRates = rarityRates;\n this.validateConfig();\n }\n\n private validateConfig(): void {\n const configuredRarities = new Set(Object.keys(this.rarityRates));\n const usedRarities = new Set(this.pools.map(p => p.rarity));\n const missingArray = Array.from(usedRarities).filter(r => !configuredRarities.has(r));\n if (missingArray.length > 0) {\n throw new Error(`Missing rarity rates for: ${missingArray.join(', ')}`);\n }\n\n for (const pool of this.pools) {\n if (pool.items.length === 0) {\n throw new Error(`Rarity \"${pool.rarity}\" has no items`);\n }\n const totalWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n if (totalWeight <= 0) {\n throw new Error(`Rarity \"${pool.rarity}\" has zero total weight`);\n }\n }\n }\n\n getItemDropRate(name: string): number {\n if (this.dropRateCache.has(name)) {\n return this.dropRateCache.get(name)!;\n }\n\n for (const pool of this.pools) {\n const item = pool.items.find(i => i.name === name);\n if (item) {\n const totalPoolWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n const baseRarityRate = this.rarityRates[pool.rarity];\n const rate = (item.weight / totalPoolWeight) * baseRarityRate;\n this.dropRateCache.set(name, rate);\n return rate;\n }\n }\n throw new Error(`Item \"${name}\" not found`);\n }\n\n getRarityProbability(rarity: string): number {\n if (!this.rarityRates[rarity]) {\n throw new Error(`Rarity \"${rarity}\" not found`);\n }\n return this.rarityRates[rarity];\n }\n\n getCumulativeProbabilityForItem(name: string, rolls: number): number {\n const rate = this.getItemDropRate(name);\n return 1 - Math.pow(1 - rate, rolls);\n }\n\n getRollsForTargetProbability(name: string, targetProbability: number): number {\n const rate = this.getItemDropRate(name);\n if (rate <= 0) return Infinity;\n return Math.ceil(Math.log(1 - targetProbability) / Math.log(1 - rate));\n }\n\n getRateUpItems(): string[] {\n return this.pools.flatMap(p =>\n p.items.filter(i => i.rateUp).map(i => i.name)\n );\n }\n\n getAllItemDropRates(): { name: string; dropRate: number; rarity: string }[] {\n return this.pools.flatMap(p =>\n p.items.map(i => ({\n name: i.name,\n dropRate: this.getItemDropRate(i.name),\n rarity: p.rarity\n }))\n );\n }\n\n roll(count: number = 1): string[] {\n const results: string[] = [];\n for (let i = 0; i < count; i++) {\n const rarity = this.selectRarity();\n const pool = this.pools.find(p => p.rarity === rarity)!;\n const item = this.selectItemFromPool(pool);\n results.push(item.name);\n }\n return results;\n }\n\n private selectRarity(): string {\n const rand = Math.random();\n let cumulative = 0;\n for (const [rarity, rate] of Object.entries(this.rarityRates)) {\n cumulative += rate;\n if (rand <= cumulative) return rarity;\n }\n return Object.keys(this.rarityRates)[0];\n }\n\n private selectItemFromPool(pool: RarityInput): { name: string; weight: number } {\n const totalWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n const rand = Math.random() * totalWeight;\n let cumulative = 0;\n for (const item of pool.items) {\n cumulative += item.weight;\n if (rand <= cumulative) return item;\n }\n return pool.items[0];\n }\n}"],"names":["GachaEngine","_ref","rarityRates","pools","this","dropRateCache","Map","validateConfig","_proto","prototype","configuredRarities","Set","Object","keys","usedRarities","map","p","rarity","missingArray","Array","from","filter","r","has","length","Error","join","_step","_iterator","_createForOfIteratorHelperLoose","done","pool","value","items","reduce","sum","i","weight","getItemDropRate","name","get","_step2","_iterator2","item","find","totalPoolWeight","rate","set","getRarityProbability","getCumulativeProbabilityForItem","rolls","Math","pow","getRollsForTargetProbability","targetProbability","Infinity","ceil","log","getRateUpItems","flatMap","rateUp","getAllItemDropRates","_this","dropRate","roll","count","_this2","results","_loop","selectRarity","selectItemFromPool","push","rand","random","cumulative","_i","_Object$entries","entries","_Object$entries$_i","_step3","totalWeight","_iterator3"],"mappings":"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"}
|
package/dist/index.module.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
function t(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=Array(r);e<r;e++)n[e]=t[e];return n}function r(r,e){var n="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(n)return(n=n.call(r)).next.bind(n);if(Array.isArray(r)||(n=function(r,e){if(r){if("string"==typeof r)return t(r,e);var n={}.toString.call(r).slice(8,-1);return"Object"===n&&r.constructor&&(n=r.constructor.name),"Map"===n||"Set"===n?Array.from(r):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?t(r,e):void 0}}(r))||e&&r&&"number"==typeof r.length){n&&(r=n);var i=0;return function(){return i>=r.length?{done:!0}:{done:!1,value:r[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var e=/*#__PURE__*/function(){function t(t){var r=t.rarityRates,e=t.pools;this.pools=void 0,this.rarityRates=void 0,this.dropRateCache=new Map,this.pools=e,this.rarityRates=r,this.validateConfig()}var e=t.prototype;return e.validateConfig=function(){var t=new Set(Object.keys(this.rarityRates)),e=new Set(this.pools.map(function(t){return t.rarity})),n=
|
|
1
|
+
function t(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=Array(r);e<r;e++)n[e]=t[e];return n}function r(r,e){var n="undefined"!=typeof Symbol&&r[Symbol.iterator]||r["@@iterator"];if(n)return(n=n.call(r)).next.bind(n);if(Array.isArray(r)||(n=function(r,e){if(r){if("string"==typeof r)return t(r,e);var n={}.toString.call(r).slice(8,-1);return"Object"===n&&r.constructor&&(n=r.constructor.name),"Map"===n||"Set"===n?Array.from(r):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?t(r,e):void 0}}(r))||e&&r&&"number"==typeof r.length){n&&(r=n);var i=0;return function(){return i>=r.length?{done:!0}:{done:!1,value:r[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var e=/*#__PURE__*/function(){function t(t){var r=t.rarityRates,e=t.pools;this.pools=void 0,this.rarityRates=void 0,this.dropRateCache=new Map,this.pools=e,this.rarityRates=r,this.validateConfig()}var e=t.prototype;return e.validateConfig=function(){var t=new Set(Object.keys(this.rarityRates)),e=new Set(this.pools.map(function(t){return t.rarity})),n=Array.from(e).filter(function(r){return!t.has(r)});if(n.length>0)throw new Error("Missing rarity rates for: "+n.join(", "));for(var i,o=r(this.pools);!(i=o()).done;){var a=i.value;if(0===a.items.length)throw new Error('Rarity "'+a.rarity+'" has no items');if(a.items.reduce(function(t,r){return t+r.weight},0)<=0)throw new Error('Rarity "'+a.rarity+'" has zero total weight')}},e.getItemDropRate=function(t){if(this.dropRateCache.has(t))return this.dropRateCache.get(t);for(var e,n=r(this.pools);!(e=n()).done;){var i=e.value,o=i.items.find(function(r){return r.name===t});if(o){var a=i.items.reduce(function(t,r){return t+r.weight},0),s=o.weight/a*this.rarityRates[i.rarity];return this.dropRateCache.set(t,s),s}}throw new Error('Item "'+t+'" not found')},e.getRarityProbability=function(t){if(!this.rarityRates[t])throw new Error('Rarity "'+t+'" not found');return this.rarityRates[t]},e.getCumulativeProbabilityForItem=function(t,r){var e=this.getItemDropRate(t);return 1-Math.pow(1-e,r)},e.getRollsForTargetProbability=function(t,r){var e=this.getItemDropRate(t);return e<=0?Infinity:Math.ceil(Math.log(1-r)/Math.log(1-e))},e.getRateUpItems=function(){return this.pools.flatMap(function(t){return t.items.filter(function(t){return t.rateUp}).map(function(t){return t.name})})},e.getAllItemDropRates=function(){var t=this;return this.pools.flatMap(function(r){return r.items.map(function(e){return{name:e.name,dropRate:t.getItemDropRate(e.name),rarity:r.rarity}})})},e.roll=function(t){var r=this;void 0===t&&(t=1);for(var e=[],n=function(){var t=r.selectRarity(),n=r.pools.find(function(r){return r.rarity===t}),i=r.selectItemFromPool(n);e.push(i.name)},i=0;i<t;i++)n();return e},e.selectRarity=function(){for(var t=Math.random(),r=0,e=0,n=Object.entries(this.rarityRates);e<n.length;e++){var i=n[e];if(t<=(r+=i[1]))return i[0]}return Object.keys(this.rarityRates)[0]},e.selectItemFromPool=function(t){for(var e,n=t.items.reduce(function(t,r){return t+r.weight},0),i=Math.random()*n,o=0,a=r(t.items);!(e=a()).done;){var s=e.value;if(i<=(o+=s.weight))return s}return t.items[0]},t}();export{e as GachaEngine};
|
|
2
2
|
//# sourceMappingURL=index.module.js.map
|
package/dist/index.module.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.module.js","sources":["../src/gacha-engine.ts"],"sourcesContent":["import { RarityInput, GachaEngineConfig } from './types';\n\nexport class GachaEngine {\n private pools: RarityInput[];\n private rarityRates: Record<string, number>;\n private dropRateCache = new Map<string, number>();\n\n constructor({ rarityRates, pools }: GachaEngineConfig) {\n this.pools = pools;\n this.rarityRates = rarityRates;\n this.validateConfig();\n }\n\n private validateConfig(): void {\n const configuredRarities = new Set(Object.keys(this.rarityRates));\n const usedRarities = new Set(this.pools.map(p => p.rarity));\n const
|
|
1
|
+
{"version":3,"file":"index.module.js","sources":["../src/gacha-engine.ts"],"sourcesContent":["import { RarityInput, GachaEngineConfig } from './types';\n\nexport class GachaEngine {\n private pools: RarityInput[];\n private rarityRates: Record<string, number>;\n private dropRateCache = new Map<string, number>();\n\n constructor({ rarityRates, pools }: GachaEngineConfig) {\n this.pools = pools;\n this.rarityRates = rarityRates;\n this.validateConfig();\n }\n\n private validateConfig(): void {\n const configuredRarities = new Set(Object.keys(this.rarityRates));\n const usedRarities = new Set(this.pools.map(p => p.rarity));\n const missingArray = Array.from(usedRarities).filter(r => !configuredRarities.has(r));\n if (missingArray.length > 0) {\n throw new Error(`Missing rarity rates for: ${missingArray.join(', ')}`);\n }\n\n for (const pool of this.pools) {\n if (pool.items.length === 0) {\n throw new Error(`Rarity \"${pool.rarity}\" has no items`);\n }\n const totalWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n if (totalWeight <= 0) {\n throw new Error(`Rarity \"${pool.rarity}\" has zero total weight`);\n }\n }\n }\n\n getItemDropRate(name: string): number {\n if (this.dropRateCache.has(name)) {\n return this.dropRateCache.get(name)!;\n }\n\n for (const pool of this.pools) {\n const item = pool.items.find(i => i.name === name);\n if (item) {\n const totalPoolWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n const baseRarityRate = this.rarityRates[pool.rarity];\n const rate = (item.weight / totalPoolWeight) * baseRarityRate;\n this.dropRateCache.set(name, rate);\n return rate;\n }\n }\n throw new Error(`Item \"${name}\" not found`);\n }\n\n getRarityProbability(rarity: string): number {\n if (!this.rarityRates[rarity]) {\n throw new Error(`Rarity \"${rarity}\" not found`);\n }\n return this.rarityRates[rarity];\n }\n\n getCumulativeProbabilityForItem(name: string, rolls: number): number {\n const rate = this.getItemDropRate(name);\n return 1 - Math.pow(1 - rate, rolls);\n }\n\n getRollsForTargetProbability(name: string, targetProbability: number): number {\n const rate = this.getItemDropRate(name);\n if (rate <= 0) return Infinity;\n return Math.ceil(Math.log(1 - targetProbability) / Math.log(1 - rate));\n }\n\n getRateUpItems(): string[] {\n return this.pools.flatMap(p =>\n p.items.filter(i => i.rateUp).map(i => i.name)\n );\n }\n\n getAllItemDropRates(): { name: string; dropRate: number; rarity: string }[] {\n return this.pools.flatMap(p =>\n p.items.map(i => ({\n name: i.name,\n dropRate: this.getItemDropRate(i.name),\n rarity: p.rarity\n }))\n );\n }\n\n roll(count: number = 1): string[] {\n const results: string[] = [];\n for (let i = 0; i < count; i++) {\n const rarity = this.selectRarity();\n const pool = this.pools.find(p => p.rarity === rarity)!;\n const item = this.selectItemFromPool(pool);\n results.push(item.name);\n }\n return results;\n }\n\n private selectRarity(): string {\n const rand = Math.random();\n let cumulative = 0;\n for (const [rarity, rate] of Object.entries(this.rarityRates)) {\n cumulative += rate;\n if (rand <= cumulative) return rarity;\n }\n return Object.keys(this.rarityRates)[0];\n }\n\n private selectItemFromPool(pool: RarityInput): { name: string; weight: number } {\n const totalWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n const rand = Math.random() * totalWeight;\n let cumulative = 0;\n for (const item of pool.items) {\n cumulative += item.weight;\n if (rand <= cumulative) return item;\n }\n return pool.items[0];\n }\n}"],"names":["GachaEngine","_ref","rarityRates","pools","this","dropRateCache","Map","validateConfig","_proto","prototype","configuredRarities","Set","Object","keys","usedRarities","map","p","rarity","missingArray","Array","from","filter","r","has","length","Error","join","_step","_iterator","_createForOfIteratorHelperLoose","done","pool","value","items","reduce","sum","i","weight","getItemDropRate","name","get","_step2","_iterator2","item","find","totalPoolWeight","rate","set","getRarityProbability","getCumulativeProbabilityForItem","rolls","Math","pow","getRollsForTargetProbability","targetProbability","Infinity","ceil","log","getRateUpItems","flatMap","rateUp","getAllItemDropRates","_this","dropRate","roll","count","_this2","results","_loop","selectRarity","selectItemFromPool","push","rand","random","cumulative","_i","_Object$entries","entries","_Object$entries$_i","_step3","totalWeight","_iterator3"],"mappings":"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"}
|
package/dist/index.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t||self).AllemandiGachaEngine={})}(this,function(t){function r(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=Array(r);e<r;e++)n[e]=t[e];return n}function e(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(n)return(n=n.call(t)).next.bind(n);if(Array.isArray(t)||(n=function(t,e){if(t){if("string"==typeof t)return r(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){n&&(t=n);var i=0;return function(){return i>=t.length?{done:!0}:{done:!1,value:t[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}t.GachaEngine=/*#__PURE__*/function(){function t(t){var r=t.rarityRates,e=t.pools;this.pools=void 0,this.rarityRates=void 0,this.dropRateCache=new Map,this.pools=e,this.rarityRates=r,this.validateConfig()}var r=t.prototype;return r.validateConfig=function(){var t=new Set(Object.keys(this.rarityRates)),r=new Set(this.pools.map(function(t){return t.rarity})),n=
|
|
1
|
+
!function(t,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((t||self).AllemandiGachaEngine={})}(this,function(t){function r(t,r){(null==r||r>t.length)&&(r=t.length);for(var e=0,n=Array(r);e<r;e++)n[e]=t[e];return n}function e(t,e){var n="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(n)return(n=n.call(t)).next.bind(n);if(Array.isArray(t)||(n=function(t,e){if(t){if("string"==typeof t)return r(t,e);var n={}.toString.call(t).slice(8,-1);return"Object"===n&&t.constructor&&(n=t.constructor.name),"Map"===n||"Set"===n?Array.from(t):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?r(t,e):void 0}}(t))||e&&t&&"number"==typeof t.length){n&&(t=n);var i=0;return function(){return i>=t.length?{done:!0}:{done:!1,value:t[i++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}t.GachaEngine=/*#__PURE__*/function(){function t(t){var r=t.rarityRates,e=t.pools;this.pools=void 0,this.rarityRates=void 0,this.dropRateCache=new Map,this.pools=e,this.rarityRates=r,this.validateConfig()}var r=t.prototype;return r.validateConfig=function(){var t=new Set(Object.keys(this.rarityRates)),r=new Set(this.pools.map(function(t){return t.rarity})),n=Array.from(r).filter(function(r){return!t.has(r)});if(n.length>0)throw new Error("Missing rarity rates for: "+n.join(", "));for(var i,o=e(this.pools);!(i=o()).done;){var a=i.value;if(0===a.items.length)throw new Error('Rarity "'+a.rarity+'" has no items');if(a.items.reduce(function(t,r){return t+r.weight},0)<=0)throw new Error('Rarity "'+a.rarity+'" has zero total weight')}},r.getItemDropRate=function(t){if(this.dropRateCache.has(t))return this.dropRateCache.get(t);for(var r,n=e(this.pools);!(r=n()).done;){var i=r.value,o=i.items.find(function(r){return r.name===t});if(o){var a=i.items.reduce(function(t,r){return t+r.weight},0),s=o.weight/a*this.rarityRates[i.rarity];return this.dropRateCache.set(t,s),s}}throw new Error('Item "'+t+'" not found')},r.getRarityProbability=function(t){if(!this.rarityRates[t])throw new Error('Rarity "'+t+'" not found');return this.rarityRates[t]},r.getCumulativeProbabilityForItem=function(t,r){var e=this.getItemDropRate(t);return 1-Math.pow(1-e,r)},r.getRollsForTargetProbability=function(t,r){var e=this.getItemDropRate(t);return e<=0?Infinity:Math.ceil(Math.log(1-r)/Math.log(1-e))},r.getRateUpItems=function(){return this.pools.flatMap(function(t){return t.items.filter(function(t){return t.rateUp}).map(function(t){return t.name})})},r.getAllItemDropRates=function(){var t=this;return this.pools.flatMap(function(r){return r.items.map(function(e){return{name:e.name,dropRate:t.getItemDropRate(e.name),rarity:r.rarity}})})},r.roll=function(t){var r=this;void 0===t&&(t=1);for(var e=[],n=function(){var t=r.selectRarity(),n=r.pools.find(function(r){return r.rarity===t}),i=r.selectItemFromPool(n);e.push(i.name)},i=0;i<t;i++)n();return e},r.selectRarity=function(){for(var t=Math.random(),r=0,e=0,n=Object.entries(this.rarityRates);e<n.length;e++){var i=n[e];if(t<=(r+=i[1]))return i[0]}return Object.keys(this.rarityRates)[0]},r.selectItemFromPool=function(t){for(var r,n=t.items.reduce(function(t,r){return t+r.weight},0),i=Math.random()*n,o=0,a=e(t.items);!(r=a()).done;){var s=r.value;if(i<=(o+=s.weight))return s}return t.items[0]},t}()});
|
|
2
2
|
//# sourceMappingURL=index.umd.js.map
|
package/dist/index.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.js","sources":["../src/gacha-engine.ts"],"sourcesContent":["import { RarityInput, GachaEngineConfig } from './types';\n\nexport class GachaEngine {\n private pools: RarityInput[];\n private rarityRates: Record<string, number>;\n private dropRateCache = new Map<string, number>();\n\n constructor({ rarityRates, pools }: GachaEngineConfig) {\n this.pools = pools;\n this.rarityRates = rarityRates;\n this.validateConfig();\n }\n\n private validateConfig(): void {\n const configuredRarities = new Set(Object.keys(this.rarityRates));\n const usedRarities = new Set(this.pools.map(p => p.rarity));\n const
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/gacha-engine.ts"],"sourcesContent":["import { RarityInput, GachaEngineConfig } from './types';\n\nexport class GachaEngine {\n private pools: RarityInput[];\n private rarityRates: Record<string, number>;\n private dropRateCache = new Map<string, number>();\n\n constructor({ rarityRates, pools }: GachaEngineConfig) {\n this.pools = pools;\n this.rarityRates = rarityRates;\n this.validateConfig();\n }\n\n private validateConfig(): void {\n const configuredRarities = new Set(Object.keys(this.rarityRates));\n const usedRarities = new Set(this.pools.map(p => p.rarity));\n const missingArray = Array.from(usedRarities).filter(r => !configuredRarities.has(r));\n if (missingArray.length > 0) {\n throw new Error(`Missing rarity rates for: ${missingArray.join(', ')}`);\n }\n\n for (const pool of this.pools) {\n if (pool.items.length === 0) {\n throw new Error(`Rarity \"${pool.rarity}\" has no items`);\n }\n const totalWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n if (totalWeight <= 0) {\n throw new Error(`Rarity \"${pool.rarity}\" has zero total weight`);\n }\n }\n }\n\n getItemDropRate(name: string): number {\n if (this.dropRateCache.has(name)) {\n return this.dropRateCache.get(name)!;\n }\n\n for (const pool of this.pools) {\n const item = pool.items.find(i => i.name === name);\n if (item) {\n const totalPoolWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n const baseRarityRate = this.rarityRates[pool.rarity];\n const rate = (item.weight / totalPoolWeight) * baseRarityRate;\n this.dropRateCache.set(name, rate);\n return rate;\n }\n }\n throw new Error(`Item \"${name}\" not found`);\n }\n\n getRarityProbability(rarity: string): number {\n if (!this.rarityRates[rarity]) {\n throw new Error(`Rarity \"${rarity}\" not found`);\n }\n return this.rarityRates[rarity];\n }\n\n getCumulativeProbabilityForItem(name: string, rolls: number): number {\n const rate = this.getItemDropRate(name);\n return 1 - Math.pow(1 - rate, rolls);\n }\n\n getRollsForTargetProbability(name: string, targetProbability: number): number {\n const rate = this.getItemDropRate(name);\n if (rate <= 0) return Infinity;\n return Math.ceil(Math.log(1 - targetProbability) / Math.log(1 - rate));\n }\n\n getRateUpItems(): string[] {\n return this.pools.flatMap(p =>\n p.items.filter(i => i.rateUp).map(i => i.name)\n );\n }\n\n getAllItemDropRates(): { name: string; dropRate: number; rarity: string }[] {\n return this.pools.flatMap(p =>\n p.items.map(i => ({\n name: i.name,\n dropRate: this.getItemDropRate(i.name),\n rarity: p.rarity\n }))\n );\n }\n\n roll(count: number = 1): string[] {\n const results: string[] = [];\n for (let i = 0; i < count; i++) {\n const rarity = this.selectRarity();\n const pool = this.pools.find(p => p.rarity === rarity)!;\n const item = this.selectItemFromPool(pool);\n results.push(item.name);\n }\n return results;\n }\n\n private selectRarity(): string {\n const rand = Math.random();\n let cumulative = 0;\n for (const [rarity, rate] of Object.entries(this.rarityRates)) {\n cumulative += rate;\n if (rand <= cumulative) return rarity;\n }\n return Object.keys(this.rarityRates)[0];\n }\n\n private selectItemFromPool(pool: RarityInput): { name: string; weight: number } {\n const totalWeight = pool.items.reduce((sum, i) => sum + i.weight, 0);\n const rand = Math.random() * totalWeight;\n let cumulative = 0;\n for (const item of pool.items) {\n cumulative += item.weight;\n if (rand <= cumulative) return item;\n }\n return pool.items[0];\n }\n}"],"names":["GachaEngine","_ref","rarityRates","pools","this","dropRateCache","Map","validateConfig","_proto","prototype","configuredRarities","Set","Object","keys","usedRarities","map","p","rarity","missingArray","Array","from","filter","r","has","length","Error","join","_step","_iterator","_createForOfIteratorHelperLoose","done","pool","value","items","reduce","sum","i","weight","getItemDropRate","name","get","_step2","_iterator2","item","find","totalPoolWeight","rate","set","getRarityProbability","getCumulativeProbabilityForItem","rolls","Math","pow","getRollsForTargetProbability","targetProbability","Infinity","ceil","log","getRateUpItems","flatMap","rateUp","getAllItemDropRates","_this","dropRate","roll","count","_this2","results","_loop","selectRarity","selectItemFromPool","push","rand","random","cumulative","_i","_Object$entries","entries","_Object$entries$_i","_step3","totalWeight","_iterator3"],"mappings":"6iCAEwB,WAKpB,SAAAA,EAAAC,GAAqD,IAAvCC,EAAWD,EAAXC,YAAaC,EAAKF,EAALE,MAAKC,KAJxBD,WAAK,EAAAC,KACLF,iBAAW,EAAAE,KACXC,cAAgB,IAAIC,IAGxBF,KAAKD,MAAQA,EACbC,KAAKF,YAAcA,EACnBE,KAAKG,gBACT,CAAC,IAAAC,EAAAR,EAAAS,UAuGA,OAvGAD,EAEOD,eAAA,WACJ,IAAMG,EAAqB,IAAIC,IAAIC,OAAOC,KAAKT,KAAKF,cAC9CY,EAAe,IAAIH,IAAIP,KAAKD,MAAMY,IAAI,SAAAC,GAAK,OAAAA,EAAEC,MAAM,IACnDC,EAAeC,MAAMC,KAAKN,GAAcO,OAAO,SAAAC,GAAC,OAAKZ,EAAmBa,IAAID,EAAE,GACpF,GAAIJ,EAAaM,OAAS,EACtB,MAAU,IAAAC,MAAK,6BAA8BP,EAAaQ,KAAK,OAGnE,IAAA,IAA6BC,EAA7BC,EAAAC,EAAmBzB,KAAKD,SAAKwB,EAAAC,KAAAE,MAAE,CAAA,IAApBC,EAAIJ,EAAAK,MACX,GAA0B,IAAtBD,EAAKE,MAAMT,OACX,UAAUC,MAAiBM,WAAAA,EAAKd,OAAsB,kBAG1D,GADoBc,EAAKE,MAAMC,OAAO,SAACC,EAAKC,GAAM,OAAAD,EAAMC,EAAEC,MAAM,EAAE,IAC/C,EACf,MAAM,IAAIZ,iBAAiBM,EAAKd,OAAM,0BAE9C,CACJ,EAACT,EAED8B,gBAAA,SAAgBC,GACZ,GAAInC,KAAKC,cAAckB,IAAIgB,GACvB,OAAWnC,KAACC,cAAcmC,IAAID,GAGlC,IAAA,IAA6BE,EAA7BC,EAAAb,EAAmBzB,KAAKD,SAAKsC,EAAAC,KAAAZ,MAAE,CAAA,IAApBC,EAAIU,EAAAT,MACLW,EAAOZ,EAAKE,MAAMW,KAAK,SAAAR,GAAK,OAAAA,EAAEG,OAASA,CAAI,GACjD,GAAII,EAAM,CACN,IAAME,EAAkBd,EAAKE,MAAMC,OAAO,SAACC,EAAKC,GAAC,OAAKD,EAAMC,EAAEC,MAAM,EAAE,GAEhES,EAAQH,EAAKN,OAASQ,EADLzC,KAAKF,YAAY6B,EAAKd,QAG7C,OADAb,KAAKC,cAAc0C,IAAIR,EAAMO,GACtBA,CACX,CACJ,CACA,MAAU,IAAArB,MAAK,SAAUc,EAAiB,cAC9C,EAAC/B,EAEDwC,qBAAA,SAAqB/B,GACjB,IAAKb,KAAKF,YAAYe,GAClB,MAAM,IAAIQ,iBAAiBR,EAAM,eAErC,OAAOb,KAAKF,YAAYe,EAC5B,EAACT,EAEDyC,gCAAA,SAAgCV,EAAcW,GAC1C,IAAMJ,EAAO1C,KAAKkC,gBAAgBC,GAClC,OAAO,EAAIY,KAAKC,IAAI,EAAIN,EAAMI,EAClC,EAAC1C,EAED6C,6BAAA,SAA6Bd,EAAce,GACvC,IAAMR,EAAO1C,KAAKkC,gBAAgBC,GAClC,OAAIO,GAAQ,EAAUS,SACfJ,KAAKK,KAAKL,KAAKM,IAAI,EAAIH,GAAqBH,KAAKM,IAAI,EAAIX,GACpE,EAACtC,EAEDkD,eAAA,WACI,OAAOtD,KAAKD,MAAMwD,QAAQ,SAAA3C,GAAC,OACvBA,EAAEiB,MAAMZ,OAAO,SAAAe,GAAK,OAAAA,EAAEwB,MAAM,GAAE7C,IAAI,SAAAqB,GAAK,OAAAA,EAAEG,IAAI,EAAC,EAEtD,EAAC/B,EAEDqD,oBAAA,WAAmBC,IAAAA,EACf1D,KAAA,YAAYD,MAAMwD,QAAQ,SAAA3C,GACtB,OAAAA,EAAEiB,MAAMlB,IAAI,SAAAqB,GAAM,MAAA,CACdG,KAAMH,EAAEG,KACRwB,SAAUD,EAAKxB,gBAAgBF,EAAEG,MACjCtB,OAAQD,EAAEC,OACb,EAAE,EAEX,EAACT,EAEDwD,KAAA,SAAKC,GAAiBC,IAAAA,gBAAjBD,IAAAA,EAAgB,GAEjB,IADA,IAAME,EAAoB,GAAGC,EAAA,WAEzB,IAAMnD,EAASiD,EAAKG,eACdtC,EAAOmC,EAAK/D,MAAMyC,KAAK,SAAA5B,GAAC,OAAIA,EAAEC,SAAWA,CAAM,GAC/C0B,EAAOuB,EAAKI,mBAAmBvC,GACrCoC,EAAQI,KAAK5B,EAAKJ,KACtB,EALSH,EAAI,EAAGA,EAAI6B,EAAO7B,IAAGgC,IAM9B,OAAOD,CACX,EAAC3D,EAEO6D,aAAA,WAGJ,IAFA,IAAMG,EAAOrB,KAAKsB,SACdC,EAAa,EACjBC,EAAAC,EAAAA,EAA6BhE,OAAOiE,QAAQzE,KAAKF,aAAYyE,EAAAC,EAAApD,OAAAmD,IAAE,CAA1D,IAAAG,EAAAF,EAAAD,GAED,GAAIH,IADJE,GADoBI,EAAA,IAEI,OAFVA,EAAA,EAGlB,CACA,OAAOlE,OAAOC,KAAKT,KAAKF,aAAa,EACzC,EAACM,EAEO8D,mBAAA,SAAmBvC,GAIvB,IAHA,IAG6BgD,EAHvBC,EAAcjD,EAAKE,MAAMC,OAAO,SAACC,EAAKC,GAAC,OAAKD,EAAMC,EAAEC,MAAM,EAAE,GAC5DmC,EAAOrB,KAAKsB,SAAWO,EACzBN,EAAa,EACjBO,EAAApD,EAAmBE,EAAKE,SAAK8C,EAAAE,KAAAnD,MAAE,CAAA,IAApBa,EAAIoC,EAAA/C,MAEX,GAAIwC,IADJE,GAAc/B,EAAKN,QACK,OAAOM,CACnC,CACA,OAAOZ,EAAKE,MAAM,EACtB,EAACjC,CAAA,CAhHmB"}
|
package/package.json
CHANGED