55 lines
1.9 KiB
TypeScript
55 lines
1.9 KiB
TypeScript
import { Course, Bar } from 'tja-parser';
|
|
|
|
export namespace Factor {
|
|
// 노트 추출 및 정렬 (시간순)
|
|
export function getAllNotes(course: Course) {
|
|
const notes: { type: number, time: number }[] = [];
|
|
for (const group of course.noteGroups) {
|
|
if (group instanceof Bar) {
|
|
// 파서 구조에 따라 노트 추출 방식 조정 필요
|
|
notes.push(...group.getNotes().map((note) => {
|
|
return {
|
|
//@ts-expect-error
|
|
type: note.type,
|
|
time: note.getTimingMS()
|
|
}
|
|
}));
|
|
}
|
|
}
|
|
return notes.sort((a, b) => a.time - b.time).filter(n => [1, 2, 3, 4].includes(n.type));
|
|
}
|
|
|
|
export function getAverageDensity(notes: { time: number }[]): number {
|
|
if (notes.length < 2) return 0;
|
|
const duration = (notes[notes.length - 1].time - notes[0].time) / 1000;
|
|
return duration > 0 ? notes.length / duration : 0;
|
|
}
|
|
|
|
export function getPeakDensity(notes: { time: number }[]): number {
|
|
if (notes.length === 0) return 0;
|
|
let maxPeak = 0;
|
|
const windowSize = 1000;
|
|
for (let i = 0; i < notes.length; i++) {
|
|
let count = 0;
|
|
const startTime = notes[i].time;
|
|
for (let j = i; j < notes.length && notes[j].time < startTime + windowSize; j++) {
|
|
count++;
|
|
}
|
|
maxPeak = Math.max(maxPeak, count);
|
|
}
|
|
return maxPeak;
|
|
}
|
|
|
|
export function getMaxCombo(notes: any[]): number {
|
|
return notes.length;
|
|
}
|
|
}
|
|
|
|
export function factorize(course: Course) {
|
|
const notes = Factor.getAllNotes(course);
|
|
return {
|
|
average_density: Factor.getAverageDensity(notes),
|
|
peak_density: Factor.getPeakDensity(notes),
|
|
max_combo: Factor.getMaxCombo(notes)
|
|
};
|
|
} |