import assert from 'node:assert/strict'; import test from 'node:test'; import { countOptimizationCandidates, effectiveCooldownSeconds, optimizeOrderAndCooldowns } from './index.ts'; import type { OptimizerCard, SongChartDensity } from './types.ts'; const cards: OptimizerCard[] = [ { id: 'a', name: 'A', active: { cooldownSeconds: 2, durationSeconds: 0.8, scoreUpPercent: 100 }, special: { durationSeconds: 1, scoreUpPercent: 200 } }, { id: 'b', name: 'B', active: { cooldownSeconds: 3, durationSeconds: 0.8, scoreUpPercent: 90 }, special: { durationSeconds: 1, scoreUpPercent: 20 } }, { id: 'c', name: 'C', active: { cooldownSeconds: 4, durationSeconds: 0.8, scoreUpPercent: 80 }, special: { durationSeconds: 1, scoreUpPercent: 20 } }, { id: 'd', name: 'D', active: { cooldownSeconds: 5, durationSeconds: 0.8, scoreUpPercent: 70 }, special: { durationSeconds: 1, scoreUpPercent: 20 } }, { id: 'e', name: 'E', active: { cooldownSeconds: 6, durationSeconds: 0.8, scoreUpPercent: 60 }, special: { durationSeconds: 1, scoreUpPercent: 20 } } ]; const chart: SongChartDensity = { songId: 'test-song', difficulty: 'expert', durationSeconds: 8, notesPerSecond: [0, 0, 1, 1, 2, 2, 12, 12], specialStartSeconds: [6, 0, 1, 2, 3] }; test('쿨타임 감소는 기존 계산기의 나눗셈 규칙을 따른다', () => { assert.equal(effectiveCooldownSeconds(20, 0), 20); assert.equal(effectiveCooldownSeconds(20, 4), 20 / 1.04); assert.equal(effectiveCooldownSeconds(20, 12), 20 / 1.12); }); test('5장과 네 가지 감소율은 122,880개 후보를 만든다', () => { assert.equal(countOptimizationCandidates(cards), 122_880); }); test('노트가 몰린 첫 스페셜 슬롯에 가장 강한 스페셜 카드를 배치한다', () => { const fixedReductionCards = cards.map((card) => ({ ...card, allowedCooldownReductions: [0] as const })); const result = optimizeOrderAndCooldowns(fixedReductionCards, chart); assert.equal(result.order[0], 'a'); assert.ok(result.scoreWeight > 0); });