69 lines
2.3 KiB
TypeScript
69 lines
2.3 KiB
TypeScript
import type { GameState } from '@ai-tycoon/shared';
|
|
import {
|
|
INITIAL_SETTINGS, SAVE_VERSION,
|
|
INITIAL_ECONOMY, INITIAL_INFRASTRUCTURE, INITIAL_COMPUTE,
|
|
INITIAL_RESEARCH, INITIAL_MODELS, INITIAL_MARKET,
|
|
INITIAL_COMPETITORS, INITIAL_TALENT, INITIAL_DATA,
|
|
INITIAL_REPUTATION, INITIAL_ACHIEVEMENTS,
|
|
} from '@ai-tycoon/shared';
|
|
|
|
export type DeepPartial<T> = T extends object
|
|
? { [K in keyof T]?: DeepPartial<T[K]> }
|
|
: T;
|
|
|
|
function deepMerge<T>(target: T, source: DeepPartial<T>): T {
|
|
if (source === undefined || source === null) return target;
|
|
if (typeof target !== 'object' || target === null) return source as T;
|
|
if (Array.isArray(source)) return source as unknown as T;
|
|
|
|
const result = { ...target };
|
|
for (const key of Object.keys(source) as (keyof T)[]) {
|
|
const srcVal = source[key];
|
|
if (srcVal === undefined) continue;
|
|
const tgtVal = result[key];
|
|
if (
|
|
typeof tgtVal === 'object' && tgtVal !== null && !Array.isArray(tgtVal) &&
|
|
typeof srcVal === 'object' && srcVal !== null && !Array.isArray(srcVal)
|
|
) {
|
|
result[key] = deepMerge(tgtVal, srcVal as DeepPartial<typeof tgtVal>);
|
|
} else {
|
|
result[key] = srcVal as T[keyof T];
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
function baseState(): GameState {
|
|
return {
|
|
meta: {
|
|
saveVersion: SAVE_VERSION,
|
|
companyName: 'TestCorp',
|
|
currentEra: 'startup',
|
|
tickCount: 0,
|
|
lastTickTimestamp: Date.now(),
|
|
gameSpeed: 1,
|
|
isPaused: false,
|
|
createdAt: Date.now(),
|
|
totalPlayTime: 0,
|
|
settings: { ...INITIAL_SETTINGS },
|
|
},
|
|
economy: structuredClone(INITIAL_ECONOMY),
|
|
infrastructure: structuredClone(INITIAL_INFRASTRUCTURE),
|
|
compute: structuredClone(INITIAL_COMPUTE),
|
|
research: structuredClone(INITIAL_RESEARCH),
|
|
models: structuredClone(INITIAL_MODELS),
|
|
market: structuredClone(INITIAL_MARKET),
|
|
competitors: structuredClone(INITIAL_COMPETITORS),
|
|
talent: structuredClone(INITIAL_TALENT),
|
|
data: structuredClone(INITIAL_DATA),
|
|
reputation: structuredClone(INITIAL_REPUTATION),
|
|
achievements: structuredClone(INITIAL_ACHIEVEMENTS),
|
|
};
|
|
}
|
|
|
|
export function createTestState(overrides?: DeepPartial<GameState>): GameState {
|
|
const state = baseState();
|
|
if (!overrides) return state;
|
|
return deepMerge(state, overrides);
|
|
}
|