fix: match scenario 2601 monthly seed progression

This commit is contained in:
2026-08-03 18:56:23 +00:00
parent 2f17584075
commit 58b9a230a7
92 changed files with 3696 additions and 587 deletions
@@ -102,6 +102,7 @@ export const buildBattleSimEnvironment = async (
maxTrainByWar: resolveNumber(constValues, ['maxTrainByWar'], DEFAULT_WAR_CONFIG.maxTrainByWar),
maxAtmosByWar: resolveNumber(constValues, ['maxAtmosByWar'], DEFAULT_WAR_CONFIG.maxAtmosByWar),
maxGeneralStat: resolveNumber(constValues, ['maxLevel'], 255),
statUpgradeLimit: resolveNumber(constValues, ['upgradeLimit'], 30),
castleCrewTypeId,
armTypes: {
footman: 1,
+7 -2
View File
@@ -37,12 +37,17 @@ export const nextStage = (stage: number): number => {
}
};
const resolveScheduledBaseMs = (state: TournamentState): number => {
const scheduled = new Date(state.nextAt).getTime();
return Number.isFinite(scheduled) ? scheduled : Date.now();
};
export const resolveNextAt = (state: TournamentState): string =>
new Date(Date.now() + Math.max(1, state.termSeconds) * 1000).toISOString();
new Date(resolveScheduledBaseMs(state) + Math.max(1, state.termSeconds) * 1000).toISOString();
export const resolveBettingCloseAt = (state: TournamentState): string => {
const bettingTermMs = Math.min(state.termSeconds * 60, 3600) * 1000;
return new Date(Date.now() + Math.max(1000, bettingTermMs)).toISOString();
return new Date(resolveScheduledBaseMs(state) + Math.max(1000, bettingTermMs)).toISOString();
};
export const resolveStatValue = (
+13 -1
View File
@@ -12,7 +12,7 @@ import type {
TournamentState,
} from '../src/tournament/types.js';
import { applyBattle, applyPreBattleStage, settleTournamentOutcome } from '../src/tournament/worker.js';
import { buildBettingPayouts } from '../src/tournament/workerHelpers.js';
import { buildBettingPayouts, resolveBettingCloseAt, resolveNextAt } from '../src/tournament/workerHelpers.js';
import type { TurnDaemonTransport } from '../src/daemon/transport.js';
class MemoryRedis {
@@ -210,6 +210,18 @@ const runTournamentToCompletion = async (options: {
const delayTick = async (): Promise<void> => new Promise((resolve) => setTimeout(resolve, 0));
describe('tournament worker schedule compatibility', () => {
it('catches up from the stored schedule instead of discarding elapsed legacy phases', () => {
const state = createTournamentState({
termSeconds: 600,
nextAt: '2026-08-02T10:00:00.000Z',
});
expect(resolveNextAt(state)).toBe('2026-08-02T10:10:00.000Z');
expect(resolveBettingCloseAt(state)).toBe('2026-08-02T11:00:00.000Z');
});
});
describe('tournament worker (in-memory)', () => {
it('당첨자가 없으면 레거시와 같이 베팅금을 지급하거나 환불하지 않는다', () => {
expect(