feat: improve analysis and release v1.0.2
This commit is contained in:
1 parent
488d652e61
commit
e259f82b69
30 files changed
+1222
-205
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { calculateExactScore } from './score.ts';
|
||||
import { skillTargetBelongsTo } from './skill-condition.ts';
|
||||
import { passiveScoreSupportByCard } from './passive-support.ts';
|
||||
import { effectiveCooldownSeconds } from './timeline.ts';
|
||||
import { COOLDOWN_REDUCTIONS } from './types.ts';
|
||||
import type {
|
||||
@@ -17,24 +17,6 @@ type CandidateProfile = {
|
||||
probability: Float64Array;
|
||||
};
|
||||
|
||||
function passiveScoreSupportByCard(order: readonly OptimizerCard[]): number[] {
|
||||
const totals = order.map(() => 0);
|
||||
order.forEach((source, sourceIndex) => {
|
||||
for (const effect of source.passiveScoreSupportEffects ?? []) {
|
||||
let indexes: number[];
|
||||
if (effect.target === 'all') indexes = order.map((_, index) => index);
|
||||
else if (effect.target === 'self') indexes = [sourceIndex];
|
||||
else indexes = order
|
||||
.map((card, index) => ({ card, index }))
|
||||
.filter(({ card }) => skillTargetBelongsTo({ type: card.type ?? '', generation: card.generation ?? '' }, effect.targetGroup ?? ''))
|
||||
.slice(0, effect.targetCount ?? order.length)
|
||||
.map(({ index }) => index);
|
||||
for (const index of indexes) totals[index] += effect.percent;
|
||||
}
|
||||
});
|
||||
return totals;
|
||||
}
|
||||
|
||||
function permutations<T>(items: readonly T[]): T[][] {
|
||||
if (items.length <= 1) return [Array.from(items)];
|
||||
const result: T[][] = [];
|
||||
@@ -242,17 +224,17 @@ export function optimizeExactOrderAndCooldowns(
|
||||
if (cards.length !== 5 || new Set(cards.map((card) => card.id)).size !== 5) {
|
||||
throw new Error('서로 다른 카드 5장이 필요합니다.');
|
||||
}
|
||||
const orders = permutations(cards);
|
||||
const reductionAssignments = assignments(cards);
|
||||
const base = baseScores(chart, options.perfectNoteScore);
|
||||
const totalCandidates = orders.length * reductionAssignments.length;
|
||||
const orderCount = cards.reduce((value, _, index) => value * (index + 1), 1);
|
||||
const totalCandidates = orderCount * reductionAssignments.length;
|
||||
let evaluatedCandidates = 0;
|
||||
let bestScore = Number.NEGATIVE_INFINITY;
|
||||
let bestOrder: OptimizerCard[] | null = null;
|
||||
let bestReductions: Record<string, CooldownReduction> | null = null;
|
||||
let bestReductionTotal = Number.POSITIVE_INFINITY;
|
||||
|
||||
for (const order of orders) {
|
||||
for (const order of permutations(cards)) {
|
||||
const profiles = makeProfiles(order, chart);
|
||||
for (const reductions of reductionAssignments) {
|
||||
const score = scoreAssignment(order, reductions, profiles, base, options.directSongScoreBonusPercent ?? 0);
|
||||
@@ -273,6 +255,7 @@ export function optimizeExactOrderAndCooldowns(
|
||||
return {
|
||||
...calculateExactScore(bestOrder, bestReductions, chart, options),
|
||||
order: bestOrder.map((card) => card.id),
|
||||
formationOrder: cards.map((card) => card.id),
|
||||
cooldownReductions: { ...bestReductions },
|
||||
...windows,
|
||||
evaluatedCandidates
|
||||
|
||||
Reference in new issue
Block a user