XP calculation for repeated intervals

This commit is contained in:
Rene Saarsoo 2020-11-20 14:14:24 +02:00
parent f134c4cf97
commit e3ed1a2e0d
2 changed files with 51 additions and 23 deletions

View File

@ -2,6 +2,7 @@ import { xp } from "./xp";
import { Interval } from "../ast";
import { Duration } from "../Duration";
import { ConstantIntensity, RangeIntensity } from "../Intensity";
import { RepeatedInterval } from "../detectRepeats";
describe("xp()", () => {
describe("ConstantIntensity interval", () => {
@ -65,16 +66,35 @@ describe("xp()", () => {
});
});
// 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
describe("Repeated interval", () => {
const createTestInterval = (seconds: number): RepeatedInterval => ({
type: "repeat",
times: 2,
intervals: [
{
type: "Interval",
duration: new Duration(seconds / 4),
intensity: new ConstantIntensity(80),
comments: [],
},
{
type: "Interval",
duration: new Duration(seconds / 4),
intensity: new ConstantIntensity(70),
comments: [],
},
],
comments: [],
});
[
[4 * 15, 11], // 1 minute
[4 * 30, 23], // 2 minutes
[4 * 60, 47], // 4 minutes
].forEach(([seconds, expectedXp]) => {
it(`${seconds}s produces ${expectedXp} XP`, () => {
expect(xp([createTestInterval(seconds)])).toEqual(expectedXp);
});
});
});
});

View File

@ -1,20 +1,28 @@
import { Interval } from "../ast";
import { sum } from "ramda";
import { RangeIntensity, ConstantIntensity, FreeIntensity } from "../Intensity";
import { RepeatedInterval } from "../detectRepeats";
import { totalDuration } from "./totalDuration";
const intervalXp = ({ intensity, duration }: Interval): number => {
if (intensity instanceof RangeIntensity) {
const intervalXp = (interval: Interval | RepeatedInterval): number => {
if (interval.type === "repeat") {
// 11 XP per minute (1 XP for every 5.1 seconds)
const duration = totalDuration(interval.intervals).seconds * interval.times;
return Math.floor(duration / 5.1);
} else {
if (interval.intensity instanceof RangeIntensity) {
// 6 XP per minute (1XP for every 10 seconds)
return Math.floor(duration.seconds / 10);
} else if (intensity instanceof ConstantIntensity) {
return Math.floor(interval.duration.seconds / 10);
} else if (interval.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) {
return Math.floor(interval.duration.seconds / 5.56);
} else if (interval.intensity instanceof FreeIntensity) {
// 5 XP per minute
return Math.round(duration.seconds / 60) * 5;
return Math.round(interval.duration.seconds / 60) * 5;
} else {
throw new Error("Unknown type of intensity");
}
}
};
export const xp = (intervals: Interval[]): number => sum(intervals.map(intervalXp));
export const xp = (intervals: (Interval | RepeatedInterval)[]): number => sum(intervals.map(intervalXp));