.
This commit is contained in:
@@ -1,86 +1,55 @@
|
||||
import { Bar, Course } from 'tja-parser';
|
||||
|
||||
export interface Factors {
|
||||
physical_density: number;
|
||||
stamina_requirement: number;
|
||||
pattern_complexity: number;
|
||||
rhythmic_complexity: number;
|
||||
reading_gimmick: number;
|
||||
}
|
||||
import { Course, Bar } from 'tja-parser';
|
||||
|
||||
export namespace Factor {
|
||||
export function getAllNotes(course: Course): any[] {
|
||||
const notes: any[] = [];
|
||||
// 노트 추출 및 정렬 (시간순)
|
||||
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());
|
||||
// 파서 구조에 따라 노트 추출 방식 조정 필요
|
||||
notes.push(...group.getNotes().map((note) => {
|
||||
return {
|
||||
//@ts-expect-error
|
||||
type: note.type,
|
||||
time: note.getTimingMS()
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
return notes;
|
||||
return notes.sort((a, b) => a.time - b.time).filter(n => [1, 2, 3, 4].includes(n.type));
|
||||
}
|
||||
|
||||
export function getPhysicalDensity(course: Course): number {
|
||||
const notes = getAllNotes(course);
|
||||
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;
|
||||
const bars = course.noteGroups.length;
|
||||
return notes.length / (bars || 1);
|
||||
}
|
||||
|
||||
export function getStaminaRequirement(course: Course): number {
|
||||
const notes = getAllNotes(course);
|
||||
let maxStream = 0;
|
||||
let currentStream = 0;
|
||||
|
||||
for (const note of notes) {
|
||||
if (note.type !== '0') {
|
||||
currentStream++;
|
||||
} else {
|
||||
maxStream = Math.max(maxStream, currentStream);
|
||||
currentStream = 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 Math.max(maxStream, currentStream) / 100;
|
||||
return maxPeak;
|
||||
}
|
||||
|
||||
export function getPatternComplexity(course: Course): number {
|
||||
const notes = getAllNotes(course).filter(n => n.type === '1' || n.type === '2');
|
||||
let transitions = 0;
|
||||
|
||||
for (let i = 1; i < notes.length; i++) {
|
||||
if (notes[i].type !== notes[i-1].type) {
|
||||
transitions++;
|
||||
}
|
||||
}
|
||||
return notes.length > 0 ? transitions / notes.length : 0;
|
||||
}
|
||||
|
||||
export function getRhythmicComplexity(course: Course): number {
|
||||
let complexNotes = 0;
|
||||
const allNotes = getAllNotes(course);
|
||||
for (const group of course.noteGroups) {
|
||||
if (group instanceof Bar) {
|
||||
const division = group.getNotes().length;
|
||||
if (division % 4 !== 0 || division > 16) {
|
||||
complexNotes += division;
|
||||
}
|
||||
}
|
||||
}
|
||||
return allNotes.length > 0 ? complexNotes / allNotes.length : 0;
|
||||
}
|
||||
|
||||
export function getReadingGimmick(course: Course): number {
|
||||
// BPM 변화나 Scroll 변화 빈도 측정
|
||||
// tja-parser의 구조에 따라 구현 (여기서는 placeholder)
|
||||
return 0;
|
||||
export function getMaxCombo(notes: any[]): number {
|
||||
return notes.length;
|
||||
}
|
||||
}
|
||||
|
||||
export function factorize(course: Course): Factors {
|
||||
export function factorize(course: Course) {
|
||||
const notes = Factor.getAllNotes(course);
|
||||
return {
|
||||
physical_density: Factor.getPhysicalDensity(course),
|
||||
stamina_requirement: Factor.getStaminaRequirement(course),
|
||||
pattern_complexity: Factor.getPatternComplexity(course),
|
||||
rhythmic_complexity: Factor.getRhythmicComplexity(course),
|
||||
reading_gimmick: Factor.getReadingGimmick(course)
|
||||
average_density: Factor.getAverageDensity(notes),
|
||||
peak_density: Factor.getPeakDensity(notes),
|
||||
max_combo: Factor.getMaxCombo(notes)
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user