Initial scaffold: AI Tycoon monorepo with core game loop
Turborepo monorepo with three packages: - packages/shared: TypeScript types for all 14 game systems + balance constants + formatting utils - packages/game-engine: Pure TS simulation engine with tick processor, economy, infrastructure, compute, research, market, and reputation systems - apps/web: React + Vite + Tailwind + Zustand frontend with sidebar dashboard layout, new game screen, dashboard with charts, infrastructure management, and model training pages Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
import type { GameState, InfrastructureState } from '@ai-tycoon/shared';
|
||||
import {
|
||||
GPU_CONFIGS,
|
||||
LOCATION_CONFIGS,
|
||||
GPU_PRICE_VOLATILITY,
|
||||
GPU_FAILURE_RATE_BASE,
|
||||
REDUNDANCY_FAILURE_REDUCTION,
|
||||
BASE_ENERGY_COST_PER_FLOP,
|
||||
BASE_MAINTENANCE_PER_GPU,
|
||||
} from '@ai-tycoon/shared';
|
||||
import type { GpuType } from '@ai-tycoon/shared';
|
||||
|
||||
export function processInfrastructure(state: GameState): InfrastructureState {
|
||||
const dataCenters = state.infrastructure.dataCenters.map(dc => {
|
||||
const location = LOCATION_CONFIGS[dc.location];
|
||||
|
||||
const gpus = dc.gpus.map(inv => {
|
||||
const failureRate = GPU_FAILURE_RATE_BASE * (1 - dc.redundancyLevel * REDUNDANCY_FAILURE_REDUCTION);
|
||||
let newFailed = inv.failedCount;
|
||||
for (let i = 0; i < inv.healthyCount; i++) {
|
||||
if (Math.random() < failureRate) newFailed++;
|
||||
}
|
||||
const healthyCount = Math.max(0, inv.count - newFailed);
|
||||
return { ...inv, healthyCount, failedCount: newFailed };
|
||||
});
|
||||
|
||||
let totalFlops = 0;
|
||||
let totalPower = 0;
|
||||
let totalGpuCount = 0;
|
||||
for (const inv of gpus) {
|
||||
const config = GPU_CONFIGS[inv.type];
|
||||
totalFlops += inv.healthyCount * config.flopsPerUnit;
|
||||
totalPower += inv.healthyCount * config.basePowerDraw;
|
||||
totalGpuCount += inv.count;
|
||||
}
|
||||
|
||||
const energyCostPerTick = totalPower * BASE_ENERGY_COST_PER_FLOP * location.energyCostMultiplier;
|
||||
const maintenanceCostPerTick = totalGpuCount * BASE_MAINTENANCE_PER_GPU;
|
||||
const currentUptime = totalGpuCount > 0
|
||||
? gpus.reduce((s, inv) => s + inv.healthyCount, 0) / totalGpuCount
|
||||
: 1;
|
||||
|
||||
return { ...dc, gpus, energyCostPerTick, maintenanceCostPerTick, currentUptime };
|
||||
});
|
||||
|
||||
const gpuMarketPrices = { ...state.infrastructure.gpuMarketPrices };
|
||||
for (const gpuType of Object.keys(gpuMarketPrices) as GpuType[]) {
|
||||
const basePrice = GPU_CONFIGS[gpuType].basePrice;
|
||||
const variation = (Math.random() - 0.5) * 2 * GPU_PRICE_VOLATILITY;
|
||||
const currentPrice = gpuMarketPrices[gpuType];
|
||||
const newPrice = currentPrice * (1 + variation);
|
||||
gpuMarketPrices[gpuType] = Math.max(basePrice * 0.7, Math.min(basePrice * 1.5, newPrice));
|
||||
}
|
||||
|
||||
let totalFlops = 0;
|
||||
let totalUptime = 0;
|
||||
let dcCount = 0;
|
||||
for (const dc of dataCenters) {
|
||||
for (const inv of dc.gpus) {
|
||||
totalFlops += inv.healthyCount * GPU_CONFIGS[inv.type].flopsPerUnit;
|
||||
}
|
||||
totalUptime += dc.currentUptime;
|
||||
dcCount++;
|
||||
}
|
||||
|
||||
return {
|
||||
dataCenters,
|
||||
gpuMarketPrices,
|
||||
totalFlops,
|
||||
totalUptime: dcCount > 0 ? totalUptime / dcCount : 1,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user