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) }; }