generated from raulanatol/template-ts-package
-
Notifications
You must be signed in to change notification settings - Fork 0
/
calculateStats.ts
92 lines (77 loc) · 2.11 KB
/
calculateStats.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { Arrow, Stepchart, Stats } from "./types.js";
// eslint-disable-next-line jsdoc/require-jsdoc
function isJump(d: Arrow["direction"]): boolean {
const nonZeroes = d.split("").reduce<number>((total, cardinal) => {
if (cardinal !== "0") {
return total + 1;
}
return total;
}, 0);
return nonZeroes === 2;
}
// eslint-disable-next-line jsdoc/require-jsdoc
function isFreeze(d: Arrow["direction"]): boolean {
return d.indexOf("2") > -1;
}
// eslint-disable-next-line jsdoc/require-jsdoc
function isGallop(
d: Arrow,
p: Arrow | undefined,
g: Arrow | undefined,
): boolean {
if (!p) {
return false;
}
if (d.quantization !== 4) {
return false;
}
// jumps are never gallops
if (isJump(d.direction)) {
return false;
}
// the gallop must move to a new direction,
// otherwise it's at the least a mini jack
if (d.direction === p.direction) {
return false;
}
if (p.quantization >= 12) {
// only consider it a gallop if it's isolated
if (!g || p.offset - g.offset >= 1 / 8) {
return d.offset - p.offset < 1 / 8;
}
}
return false;
}
// eslint-disable-next-line jsdoc/require-jsdoc
function isJack(d: Arrow, p: Arrow | undefined): boolean {
if (!p) {
return false;
}
if (isJump(d.direction)) {
return false;
}
if (d.direction !== p.direction) {
return false;
}
return d.offset - p.offset <= 1 / 8;
}
/**
* Calculate human-relevant stats for a given chart
* @param chart parsed chart object
* @returns counts for the number of jumps, jacks, freezes, and gallops
*/
export function calculateStats(chart: Stepchart): Stats {
// TODO: extend to recognize crossovers, scoobies, and more tech?
const jumps = chart.arrows.filter((a) => isJump(a.direction));
const freezes = chart.arrows.filter((a) => isFreeze(a.direction));
const gallops = chart.arrows.filter((a, i, array) =>
isGallop(a, array[i - 1], array[i - 2]),
);
const jacks = chart.arrows.filter((a, i, array) => isJack(a, array[i - 1]));
return {
jumps: jumps.length,
jacks: jacks.length,
freezes: freezes.length,
gallops: gallops.length,
};
}