Initial XP calculations

This commit is contained in:
Rene Saarsoo 2020-11-20 13:21:54 +02:00
parent 1d3bdf8e30
commit f134c4cf97
2 changed files with 100 additions and 0 deletions

80
src/stats/xp.test.ts Normal file
View File

@ -0,0 +1,80 @@
import { xp } from "./xp";
import { Interval } from "../ast";
import { Duration } from "../Duration";
import { ConstantIntensity, RangeIntensity } from "../Intensity";
describe("xp()", () => {
describe("ConstantIntensity interval", () => {
const createTestInterval = (seconds: number): Interval => ({
type: "Interval",
duration: new Duration(seconds),
intensity: new ConstantIntensity(100),
comments: [],
});
[
[1, 0],
[2, 0],
[5, 0],
[10, 1],
[15, 2],
[30, 5],
[45, 8],
[50, 8],
[55, 9],
[56, 10],
[57, 10],
[58, 10],
[59, 10],
[60, 10],
[61, 10],
[62, 11],
[63, 11],
[64, 11],
[65, 11],
[1, 0],
[1, 0],
].forEach(([seconds, expectedXp]) => {
it(`${seconds}s produces ${expectedXp} XP`, () => {
expect(xp([createTestInterval(seconds)])).toEqual(expectedXp);
});
});
});
describe("RangeIntensity interval", () => {
const createTestInterval = (seconds: number): Interval => ({
type: "Warmup",
duration: new Duration(seconds),
intensity: new RangeIntensity(50, 75),
comments: [],
});
[
[55, 5],
[56, 5],
[57, 5],
[58, 5],
[59, 5],
[60, 6],
[61, 6],
[5 * 60, 30],
].forEach(([seconds, expectedXp]) => {
it(`${seconds}s produces ${expectedXp} XP`, () => {
expect(xp([createTestInterval(seconds)])).toEqual(expectedXp);
});
});
});
// Intervals
//
// 4 x 15s = 1min --> 11 XP
// 4 x 30s = 2min --> 23 XP
// 4 x 60s = 4min --> 47 XP
// Other XP
//
// 20 XP per km
// 221 km
// 6:42 of intervals
});

20
src/stats/xp.ts Normal file
View File

@ -0,0 +1,20 @@
import { Interval } from "../ast";
import { sum } from "ramda";
import { RangeIntensity, ConstantIntensity, FreeIntensity } from "../Intensity";
const intervalXp = ({ intensity, duration }: Interval): number => {
if (intensity instanceof RangeIntensity) {
// 6 XP per minute (1XP for every 10 seconds)
return Math.floor(duration.seconds / 10);
} else if (intensity instanceof ConstantIntensity) {
// 10 XP per minute (1XP for every 5.56 seconds)
return Math.floor(duration.seconds / 5.56);
} else if (intensity instanceof FreeIntensity) {
// 5 XP per minute
return Math.round(duration.seconds / 60) * 5;
} else {
throw new Error("Unknown type of intensity");
}
};
export const xp = (intervals: Interval[]): number => sum(intervals.map(intervalXp));