rg-stats
Version:
A library for calculating various rhythm game stats.
56 lines (50 loc) • 1.55 kB
text/typescript
import { ThrowIf } from "../util/throw-if";
const RATING_COEFFICIENTS = new Map([
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
[],
]);
/**
* Calculate maimai DX Splash+ (and newer) rate for a score.
*
* @param score - The score to calculate the rate for.
* @param internalChartLevel - The internal decimal level of the chart the score was achieved on.
*/
export function calculate(score: number, internalChartLevel: number) {
ThrowIf(score > 101, "Score cannot be greater than 101%.", { score });
ThrowIf.negative(score, "Score cannot be negative.", { score });
ThrowIf.negative(internalChartLevel, "Internal chart level cannot be negative.", {
level: internalChartLevel,
});
// Scores above 100.5% are capped at 100.5% by the algorithm.
const scoreInt = Math.min(Math.round(score * 10000), 100_5000);
const iclInt = Math.round(internalChartLevel * 10);
for (const [scoreBoundary, coefficient] of RATING_COEFFICIENTS) {
if (scoreInt >= scoreBoundary) {
return Math.floor((scoreInt * coefficient * iclInt) / 100_000_000);
}
}
// should be impossible as score cannot be negative and the lowest boundary is >= 0.
/* istanbul ignore next */
throw new Error(`Unresolvable score of ${score}.`);
}