feat: save analysis results and compare growth snapshots
Publish GitHub Pages output / publish (push) Successful in 46s
Publish GitHub Pages output / publish (push) Successful in 46s
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
import type { CooldownReduction, ExactOptimizationResult } from '../engine/types.ts';
|
||||
|
||||
export type AnalysisSettings = {
|
||||
songId: string; difficulty: 'hard' | 'expert'; cardIds: string[]; awakenings: number[];
|
||||
fixedCooldownReductions?: (CooldownReduction | null)[];
|
||||
allBlueNodes?: boolean[]; generationBonusOverrides?: (number | null)[];
|
||||
songScoreBonusOverride?: number | null; leaderCharacterId: string; leaderOutfitCardId: string;
|
||||
};
|
||||
export type GrowthSnapshot = {
|
||||
collection: Record<string, { owned?: boolean; awakening?: number }>;
|
||||
memberBoards: Record<string, string[]>;
|
||||
boardCards: Record<string, Record<string, string>>;
|
||||
memoryCount: number; memberPowerUpPercent: number;
|
||||
};
|
||||
export type StoredResult = Omit<ExactOptimizationResult, 'notes' | 'scoreBySecond'>;
|
||||
export type AnalysisCapture = {
|
||||
settings: AnalysisSettings; growth: GrowthSnapshot; title: string; durationSeconds: number;
|
||||
overallPower: number; analyzedAt: string;
|
||||
};
|
||||
export type AnalysisRecord = Omit<AnalysisCapture, 'growth'> & {
|
||||
id: string; name: string; snapshotId: string; result: StoredResult;
|
||||
};
|
||||
export function compactResult(result: ExactOptimizationResult): StoredResult {
|
||||
const { notes, scoreBySecond, ...stored } = result;
|
||||
return structuredClone(stored);
|
||||
}
|
||||
// Object insertion order and board selection order must not create duplicate snapshots.
|
||||
export function snapshotKey(value: unknown): string {
|
||||
if (Array.isArray(value)) return JSON.stringify(value.map((item) => snapshotKey(item)).sort());
|
||||
if (value && typeof value === 'object') return JSON.stringify(Object.entries(value).sort(([a], [b]) => a.localeCompare(b)).map(([key, item]) => [key, snapshotKey(item)]));
|
||||
return JSON.stringify(value) ?? 'null';
|
||||
}
|
||||
export function currentGrowthSettings(settings: AnalysisSettings, growth: GrowthSnapshot): AnalysisSettings {
|
||||
const missing = settings.cardIds.filter((id) => !growth.collection[id]?.owned);
|
||||
if (missing.length) throw new Error('현재 보유 데이터에 없는 편성 카드가 있습니다. 보유 카드와 개화를 등록한 후 비교해 주세요.');
|
||||
return { ...structuredClone(settings), awakenings: settings.cardIds.map((id) => growth.collection[id]?.awakening ?? 0) };
|
||||
}
|
||||
Reference in New Issue
Block a user