fix: prioritize theoretical max score
This commit is contained in:
1 parent
a06cacb91c
commit
d85a4ddfbf
3 files changed
+65
-9
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { effectiveActiveProbability } from './active-probability.ts';
|
||||
import { calculateExactScore } from './score.ts';
|
||||
import { calculateExactScore, finalNoteScore } from './score.ts';
|
||||
import { passiveScoreSupportByCard } from './passive-support.ts';
|
||||
import { effectiveCooldownSeconds } from './timeline.ts';
|
||||
import { COOLDOWN_REDUCTIONS } from './types.ts';
|
||||
@@ -180,7 +180,7 @@ function scoreAssignment(
|
||||
profiles: ReadonlyMap<string, CandidateProfile>,
|
||||
base: Float64Array,
|
||||
directBonus: number
|
||||
): number {
|
||||
): { expectedScore: number; theoreticalMaxScore: number } {
|
||||
const selected = cards.map((card) => {
|
||||
const reduction = reductions[card.id] ?? 0;
|
||||
const profile = profiles.get(`${card.id}:${reduction}`);
|
||||
@@ -189,7 +189,8 @@ function scoreAssignment(
|
||||
});
|
||||
const boosts = new Float64Array(cards.length);
|
||||
const probabilities = new Float64Array(cards.length);
|
||||
let rawScore = 0;
|
||||
let expectedScore = 0;
|
||||
let theoreticalMaxScore = 0;
|
||||
|
||||
for (let noteIndex = 0; noteIndex < base.length; noteIndex += 1) {
|
||||
let count = 0;
|
||||
@@ -212,9 +213,10 @@ function scoreAssignment(
|
||||
expectedBoost += previousFailed * probabilities[position] * boosts[position];
|
||||
previousFailed *= 1 - probabilities[position];
|
||||
}
|
||||
rawScore += base[noteIndex] * (1 + expectedBoost);
|
||||
expectedScore += finalNoteScore(base[noteIndex] * (1 + expectedBoost), directBonus);
|
||||
theoreticalMaxScore += finalNoteScore(base[noteIndex] * (1 + (count > 0 ? boosts[0] : 0)), directBonus);
|
||||
}
|
||||
return Math.floor(Math.floor(rawScore) * (1 + directBonus / 100) + Number.EPSILON * Math.max(1, rawScore) * 4);
|
||||
return { expectedScore, theoreticalMaxScore };
|
||||
}
|
||||
|
||||
export function optimizeExactOrderAndCooldowns(
|
||||
@@ -230,7 +232,8 @@ export function optimizeExactOrderAndCooldowns(
|
||||
const orderCount = cards.reduce((value, _, index) => value * (index + 1), 1);
|
||||
const totalCandidates = orderCount * reductionAssignments.length;
|
||||
let evaluatedCandidates = 0;
|
||||
let bestScore = Number.NEGATIVE_INFINITY;
|
||||
let bestTheoreticalMaxScore = Number.NEGATIVE_INFINITY;
|
||||
let bestExpectedScore = Number.NEGATIVE_INFINITY;
|
||||
let bestOrder: OptimizerCard[] | null = null;
|
||||
let bestReductions: Record<string, CooldownReduction> | null = null;
|
||||
let bestReductionTotal = Number.POSITIVE_INFINITY;
|
||||
@@ -240,8 +243,14 @@ export function optimizeExactOrderAndCooldowns(
|
||||
for (const reductions of reductionAssignments) {
|
||||
const score = scoreAssignment(order, reductions, profiles, base, options.directSongScoreBonusPercent ?? 0);
|
||||
const reductionTotal = Object.values(reductions).reduce<number>((sum, value) => sum + value, 0);
|
||||
if (score > bestScore || (score === bestScore && reductionTotal < bestReductionTotal)) {
|
||||
bestScore = score;
|
||||
const isHigherMaximum = score.theoreticalMaxScore > bestTheoreticalMaxScore;
|
||||
const isHigherExpectedTie = score.theoreticalMaxScore === bestTheoreticalMaxScore &&
|
||||
score.expectedScore > bestExpectedScore;
|
||||
const isCheaperTie = score.theoreticalMaxScore === bestTheoreticalMaxScore &&
|
||||
score.expectedScore === bestExpectedScore && reductionTotal < bestReductionTotal;
|
||||
if (isHigherMaximum || isHigherExpectedTie || isCheaperTie) {
|
||||
bestTheoreticalMaxScore = score.theoreticalMaxScore;
|
||||
bestExpectedScore = score.expectedScore;
|
||||
bestOrder = order;
|
||||
bestReductions = reductions;
|
||||
bestReductionTotal = reductionTotal;
|
||||
|
||||
Reference in new issue
Block a user