This commit is contained in:
2026-05-13 00:28:07 +08:00
parent ef4f91a75e
commit 01c5ab985a
101 changed files with 10635 additions and 2292 deletions

View File

@@ -2,6 +2,8 @@ export {
buildLocalMatch3DOptimisticRun,
confirmLocalMatch3DClick,
MATCH3D_VISUAL_SEEDS,
normalizeLocalMatch3DRuntimeClearCount,
resolveLocalMatch3DItemTypeCount,
resolveLocalMatch3DTimer,
startLocalMatch3DRun,
stopLocalMatch3DRun,

View File

@@ -221,8 +221,23 @@ function resolveSizeTierPlan(typeCount: number) {
return baseCounts.flatMap((rule) => Array(rule.count).fill(rule));
}
export function resolveLocalMatch3DItemTypeCount(clearCount: number) {
const normalizedClearCount = Math.max(1, Math.round(clearCount));
if (normalizedClearCount === 8) return 3;
if (normalizedClearCount === 12) return 9;
if (normalizedClearCount === 16) return 15;
if (normalizedClearCount === 20 || normalizedClearCount === 21) return 21;
return Math.min(MATCH3D_MAX_ITEM_TYPE_COUNT, normalizedClearCount);
}
export function normalizeLocalMatch3DRuntimeClearCount(clearCount: number) {
const normalizedClearCount = Math.max(1, Math.round(clearCount));
// 中文注释:旧硬核草稿可能仍带 20 次消除;本地试玩按新硬核 21 组三消执行。
return normalizedClearCount === 20 ? 21 : normalizedClearCount;
}
function selectVisualSeeds(clearCount: number): Match3DSelectedVisualSeed[] {
const typeCount = Math.min(MATCH3D_MAX_ITEM_TYPE_COUNT, clearCount);
const typeCount = resolveLocalMatch3DItemTypeCount(clearCount);
const seeds = [...MATCH3D_VISUAL_SEEDS];
let state = hashNumber(clearCount * 2_654_435_761);
for (let index = seeds.length - 1; index > 0; index -= 1) {
@@ -410,7 +425,7 @@ function settleMatchedTrayItems(run: Match3DRunSnapshot) {
}
export function startLocalMatch3DRun(clearCount = 12): Match3DRunSnapshot {
const normalizedClearCount = Math.max(1, Math.round(clearCount));
const normalizedClearCount = normalizeLocalMatch3DRuntimeClearCount(clearCount);
const selectedSeeds = selectVisualSeeds(normalizedClearCount);
const items = Array.from({ length: normalizedClearCount }, (_, clearIndex) =>
Array.from({ length: 3 }, (_, copyOffset) => {

View File

@@ -5,6 +5,7 @@ import type {
Match3DClickRejectReason,
Match3DClickResponse,
Match3DRunResponse,
StartMatch3DRunRequest,
StopMatch3DRunRequest,
} from '../../../packages/shared/src/contracts/match3dRuntime';
import {
@@ -30,7 +31,9 @@ type Match3DRuntimeRequestOptions = Pick<
| 'skipRefresh'
| 'notifyAuthStateChange'
| 'clearAuthOnUnauthorized'
>;
> & {
itemTypeCountOverride?: number | null;
};
function normalizeRejectStatus(reason?: Match3DClickRejectReason | null) {
switch (reason) {
@@ -73,12 +76,17 @@ export function startMatch3DRun(
profileId: string,
options: Match3DRuntimeRequestOptions = {},
) {
const payload: StartMatch3DRunRequest = {
profileId,
itemTypeCountOverride: options.itemTypeCountOverride ?? null,
};
return requestJson<Match3DRunResponse>(
`/api/runtime/match3d/works/${encodeURIComponent(profileId)}/runs`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ profileId }),
body: JSON.stringify(payload),
},
'启动抓大鹅玩法失败',
{