feat: improve analysis and release v1.0.2
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { estimateScoreAchievementProbabilities } from './index.ts';
|
||||
import type { ExactSongChart, OptimizerCard } from './types.ts';
|
||||
|
||||
function card(
|
||||
id: string,
|
||||
scoreUpPercent: number,
|
||||
probabilityPercent: number,
|
||||
durationSeconds = 1
|
||||
): OptimizerCard {
|
||||
return {
|
||||
id,
|
||||
name: id,
|
||||
active: { cooldownSeconds: 1, durationSeconds, scoreUpPercent, probabilityPercent },
|
||||
special: { durationSeconds: 0, scoreUpPercent: 0 },
|
||||
allowedCooldownReductions: [0]
|
||||
};
|
||||
}
|
||||
|
||||
function chart(times: number[], specialStartSeconds: (number | null)[] = []): ExactSongChart {
|
||||
return {
|
||||
songId: 'test',
|
||||
difficulty: 'expert',
|
||||
durationSeconds: 5,
|
||||
scoreRatio: 1,
|
||||
notes: times.map((timeSeconds) => ({ timeSeconds, type: 'regular', isFlick: false })),
|
||||
specialStartSeconds
|
||||
};
|
||||
}
|
||||
|
||||
test('한 번의 발동이 여러 노트에 영향을 주어도 최고점 확률은 한 번만 곱한다', () => {
|
||||
const result = estimateScoreAchievementProbabilities(
|
||||
[card('main', 100, 50, 0.9)],
|
||||
{ main: 0 },
|
||||
chart([1.1, 1.5]),
|
||||
{ perfectNoteScore: 100, sampleCount: 1_000, seed: 1 }
|
||||
);
|
||||
assert.equal(result.maximum, 0.5);
|
||||
});
|
||||
|
||||
test('최고점에 영향을 주지 않는 약한 액티브는 최고점 확률에서 제외한다', () => {
|
||||
const result = estimateScoreAchievementProbabilities(
|
||||
[card('strong', 100, 50), card('weak', 20, 10)],
|
||||
{ strong: 0, weak: 0 },
|
||||
chart([1.1]),
|
||||
{ perfectNoteScore: 100, sampleCount: 1_000, seed: 2 }
|
||||
);
|
||||
assert.equal(result.maximum, 0.5);
|
||||
});
|
||||
|
||||
test('같은 최고 효과의 액티브가 겹치면 둘 중 하나가 발동할 확률을 사용한다', () => {
|
||||
const result = estimateScoreAchievementProbabilities(
|
||||
[card('left', 100, 50), card('right', 100, 50)],
|
||||
{ left: 0, right: 0 },
|
||||
chart([1.1]),
|
||||
{ perfectNoteScore: 100, sampleCount: 1_000, seed: 3 }
|
||||
);
|
||||
assert.equal(result.maximum, 0.75);
|
||||
});
|
||||
|
||||
test('스페셜의 액티브 발동률 증가를 발동 시점에 적용한다', () => {
|
||||
const main = card('main', 100, 50);
|
||||
const support: OptimizerCard = {
|
||||
...card('support', 0, 0),
|
||||
special: { durationSeconds: 3, scoreUpPercent: 0, activationRateUpPercent: 50 }
|
||||
};
|
||||
const result = estimateScoreAchievementProbabilities(
|
||||
[main, support],
|
||||
{ main: 0, support: 0 },
|
||||
chart([1.1], [null, 0]),
|
||||
{ perfectNoteScore: 100, sampleCount: 1_000, seed: 4 }
|
||||
);
|
||||
assert.equal(result.maximum, 0.75);
|
||||
});
|
||||
|
||||
test('확정 발동이면 모든 달성 확률이 100%다', () => {
|
||||
const result = estimateScoreAchievementProbabilities(
|
||||
[card('main', 100, 100)],
|
||||
{ main: 0 },
|
||||
chart([1.1, 2.1, 3.1]),
|
||||
{ perfectNoteScore: 100, sampleCount: 1_000, seed: 5 }
|
||||
);
|
||||
assert.deepEqual(result, {
|
||||
maximum: 1,
|
||||
atLeast99Percent: 1,
|
||||
atLeast95Percent: 1,
|
||||
samples: 1_000
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user