feat: add alternate outfit exclusion to combination search
Publish GitHub Pages output / publish (push) Successful in 44s

This commit is contained in:
dal4segno committed 2026-10-07 10:56:23 +09:00
1 parent d18972382a
commit dee04cb357
4 files changed
+58 -7

No files matched your search

+19 -6
View File
@@ -3,6 +3,7 @@
import { page } from '$app/stores';
import cardSummary from '$lib/data/cards-summary.json';
import { leaderOutfitCards } from '$lib/engine/leader-outfits.ts';
import { combinationCardCandidates } from '$lib/engine/combination-card-filter.ts';
import boardSummary from '$lib/data/boards-summary.json';
import memorySummary from '$lib/data/memory-summary.json';
import exactChartCatalog from '$lib/data/exact-chart-catalog.json';
@@ -87,6 +88,7 @@
fixedGenerationBonusOverrides?: (number | null)[];
songScoreBonusOverride?: number | null;
ownedCardsOnly?: boolean;
regularCardsOnly?: boolean;
maxMediumProbabilityCards?: number | null;
maximizeCompute?: boolean;
resultLimit?: number;
@@ -145,6 +147,7 @@
let fixedGenerationBonusOverrides: (number | null)[] = [null, null, null, null];
let songScoreBonusOverride: number | null = 10;
let ownedCardsOnly = false;
let regularCardsOnly = false;
let maxMediumProbabilityCards: number | null = null;
let resultLimit = 10;
let activeResultLimit = 10;
@@ -283,9 +286,7 @@
$: if (ready && connectionCards && baselineState && baselineMatchesConditions && !baselineResult && !baselineRunning && !baselineError) void analyzeBaseline();
$: if (!result && rankedResults.length > 0) rankedResults = [];
$: fixedCards = fixedCardIds.map((id) => cardById.get(id)).filter((card): card is CardRow => Boolean(card));
$: candidateCards = ownedCardsOnly
? eligibleCards.filter((card) => collection[card.id]?.owned === true)
: eligibleCards;
$: candidateCards = combinationCardCandidates(eligibleCards, collection, ownedCardsOnly, regularCardsOnly);
$: leaderMember = leaderMembers.find((card) => card.characterId === leaderCharacterId);
$: leaderOutfitOptions = leaderMember
? leaderOutfitCards(allCards, leaderCharacterId)
@@ -313,6 +314,7 @@
fixedGenerationBonusOverrides,
songScoreBonusOverride,
ownedCardsOnly,
regularCardsOnly,
maxMediumProbabilityCards,
resultLimit,
maximizeCompute,
@@ -332,6 +334,7 @@
fixedGenerationBonusOverrides,
songScoreBonusOverride,
ownedCardsOnly,
regularCardsOnly,
maxMediumProbabilityCards,
resultLimit,
maximizeCompute,
@@ -475,11 +478,12 @@
? null
: normalizeSongScoreBonusOverride(state.songScoreBonusOverride) ?? 10;
ownedCardsOnly = state.ownedCardsOnly === true;
regularCardsOnly = state.regularCardsOnly === true;
resultLimit = [10, 20, 30, 50].includes(state.resultLimit ?? 10) ? state.resultLimit ?? 10 : 10;
maxMediumProbabilityCards = typeof state.maxMediumProbabilityCards === 'number' &&
Number.isInteger(state.maxMediumProbabilityCards) && state.maxMediumProbabilityCards >= 0 && state.maxMediumProbabilityCards < 5
? state.maxMediumProbabilityCards : null;
if (ownedCardsOnly) toggleOwnedCardsOnly(true);
toggleOwnedCardsOnly(ownedCardsOnly);
maximizeCompute = state.maximizeCompute === true;
if (typeof state.leaderCharacterId === 'string' && leaderMembers.some((member) => member.characterId === state.leaderCharacterId)) {
leaderCharacterId = state.leaderCharacterId;
@@ -585,8 +589,9 @@
function toggleOwnedCardsOnly(enabled: boolean): void {
ownedCardsOnly = enabled;
if (enabled) {
const removedSlots = fixedCardIds.map((cardId) => Boolean(cardId && !collection[cardId]?.owned));
if (enabled || regularCardsOnly) {
const allowedIds = new Set(combinationCardCandidates(allCards, collection, enabled, regularCardsOnly).map((card) => card.id));
const removedSlots = fixedCardIds.map((cardId) => Boolean(cardId && !allowedIds.has(cardId)));
fixedCardIds = fixedCardIds.map((cardId, slot) => removedSlots[slot] ? '' : cardId);
fixedCooldownReductions = fixedCooldownReductions.map((value, slot) => removedSlots[slot] ? null : value);
fixedAllBlueNodes = fixedAllBlueNodes.map((value, slot) => removedSlots[slot] ? false : value);
@@ -1315,6 +1320,14 @@
<span aria-hidden="true"></span>
<strong>내가 보유한 카드만 사용하기</strong>
</label>
{#if !ownedCardsOnly}
<label class="owned-cards-option">
<input type="checkbox" checked={regularCardsOnly} disabled={running} on:change={(event) => { regularCardsOnly = event.currentTarget.checked; toggleOwnedCardsOnly(false); }}>
<span aria-hidden="true"></span>
<strong>이격 제외</strong>
</label>
<p class="candidate-guide">수영복 등 다른 의상의 이격 카드를 제외하고, 카드 목록의 ‘일반’ 분류만 고정 카드·자동 후보로 사용합니다. 제외되는 고정 카드는 해제됩니다. 현재 모집·천장 획득 가능 여부를 보장하지 않으며, 리더 의상과 연결 카드는 제한하지 않습니다.</p>
{/if}
<p class="candidate-guide">
‘내가 보유한 카드만 사용하기’를 켜면 고정 카드와 자동 후보 모두 {eventMode ? '보유한 이벤트 후보 카드' : '보유 5성 카드'}로 제한됩니다.<br>
보유 카드의 개화가 자동 후보 개화보다 높으면 실제 보유 개화를 우선 적용합니다.<br>