@nekooftheabyss/fortuna
Version:
A Gacha-like system to roll random items with weights.
95 lines (93 loc) • 2.47 kB
text/typescript
// Copyright 2022-2024 NeTT. All rights reserved. MIT license.
/**
* Data fed to the constructor.
* The `result` property holds the result that will be returned after rolling.
* `chance` is the weight of the result.
*/
export type GachaChoice<T> = {
result: T;
chance: number;
}
/**
* Gacha system.
*/
export class GachaMachine<T> {
constructor(items: GachaChoice<T>[]) {
this.
this.
this.
this.
this.
}
/** Update items in the pool. */
set items(items: GachaChoice<T>[]) {
this.
this.
}
/** Setup items for rolling. */
this.
this.
let i = 0;
while (i < items.length) {
this.
i += 1;
}
i = 0;
const multiplier = items.length / this.
const long = [],
small = [];
while (i < items.length) {
const prob = items[i].chance * multiplier;
if (prob > 1) long.push(i);
else small.push(i);
this.
this.
i += 1;
}
while (long.length && small.length) {
const j = small.pop();
const k = long.at(-1);
if (j === undefined || k === undefined) {
throw new Error(
"This definitely shouldn't happen. Open an issue at https://github.com/retraigo/fortuna"
); // this will hopefully never happen
}
this.
this.
}
}
/**
* Roll items from the gacha machine.
* ```ts
* const machine = new GachaMachine(items);
* machine.get(11)
* ```
*
* If you are looking for the `distinct` rolls,
* try importing LimitedGachaMachine instead of GachaMachine.
*/
get(count: number): T[] {
let i = 0;
const res = new Array(count);
while (i < count) {
res[i] = this.
i += 1;
}
return res;
}
const inter = Math.random() * this.
const i = ~~inter;
const y = inter - i;
return y < this.
? i
: this.
? this.
: i;
}
}