import assert from 'node:assert/strict'; import fs from 'node:fs'; import { Worker } from 'node:worker_threads'; function runWorker(seed) { return new Promise((resolve, reject) => { const worker = new Worker(new URL('./helpers-generation-worker-node-wrapper.mjs', import.meta.url), { type: 'module' }); const timer = setTimeout(() => { worker.terminate(); reject(new Error(`worker timeout seed ${seed}`)); }, 120000); worker.on('error', (error) => { clearTimeout(timer); reject(error); }); worker.on('message', async (message) => { if (message?.type !== 'result' || message.id !== seed) return; clearTimeout(timer); worker.removeAllListeners(); await worker.terminate(); if (!message.ok) reject(new Error(message.error || 'generation failed')); else resolve(message.map); }); worker.postMessage({ id: seed, seed, options: { terrainType: 'auto' } }); }); } function pathLength(paths) { let sum = 0; for (const path of paths || []) for (let i = 1; i < (path?.length || 0); i++) sum += Math.hypot(path[i][0] - path[i - 1][0], path[i][1] - path[i - 1][1]); return sum; } function maxGap(paths) { let max = 0; for (const path of paths || []) for (let i = 1; i < (path?.length || 0); i++) max = Math.max(max, Math.hypot(path[i][0] - path[i - 1][0], path[i][1] - path[i - 1][1])); return max; } function pointPathDistance(point, paths) { let best = Infinity; for (const path of paths || []) for (const q of path || []) best = Math.min(best, Math.hypot(q[0] - point.x, q[1] - point.y)); return best; } function endpointContinuityAudit(map) { const bad = []; const exp = map.expressways || []; const ordinary = [...(map.nationalRoads || []), ...(map.minorRoads || []), ...(map.externalRoads || [])]; const cities = (map.modernCities || []).filter((c) => (c.population || 0) >= 50000); for (let i = 0; i < exp.length; i++) { const path = exp[i]; if (!path?.length) continue; const others = exp.filter((_, j) => j !== i); for (const tuple of [path[0], path[path.length - 1]]) { const pt = { x: tuple[0], y: tuple[1] }; const edge = pt.x < 2 || pt.y < 2 || pt.x > map.width - 3 || pt.y > map.height - 3; const interchange = (map.interchanges || []).some((ic) => Math.hypot(ic.x - pt.x, ic.y - pt.y) <= 6.5); const city = cities.some((c) => Math.hypot(c.x - pt.x, c.y - pt.y) <= 28); const connected = edge || pointPathDistance(pt, others) <= 3.5 || pointPathDistance(pt, ordinary) <= 4.5 || interchange || city; if (!connected) bad.push({ path: i, x: pt.x, y: pt.y }); } } return bad; } const source = fs.readFileSync(new URL('../src/mapPostAdminTransport.js', import.meta.url), 'utf8'); assert(!source.includes('function directPath('), 'post-admin transport has no directPath straight-line fallback'); assert(!source.includes('function directLandConnector('), 'transport has no directLandConnector straight-line fallback'); assert(source.includes('if (gap > maxJoinGap) return []'), 'failed chain legs reject the whole trunk instead of drawing a straight chord'); assert(source.includes('removeDiscontinuousTransportPaths(2.25)'), 'final production invariant removes sparse-jump transport paths'); const map = await runWorker(1); const trunk = { national: map.nationalRoads || [], expressway: map.expressways || [], rail: [...(map.railways || []), ...(map.branchRailways || [])], }; for (const [name, paths] of Object.entries(trunk)) { assert(maxGap(paths) <= Math.SQRT2 + 1e-6, `${name}: every emitted segment is raster-contiguous; no renderer straight chord remains`); } const nationalLength = pathLength(trunk.national); const railLength = pathLength(trunk.rail); assert(nationalLength > 0 && railLength / nationalLength >= 0.80 && railLength / nationalLength <= 1.01, `rail density remains high (${(railLength / nationalLength).toFixed(3)}) and approximately national-road scale`); const expressLength = pathLength(trunk.expressway); assert((map.interchanges || []).length >= Math.max(2, Math.floor(expressLength / 18)), `IC density is sufficient for ${expressLength.toFixed(1)} expressway cells`); assert.equal(endpointContinuityAudit(map).length, 0, 'expressways have no unjustified interior dead-end endpoints'); const ordinary = [...(map.minorRoads || []), ...(map.nationalRoads || []), ...(map.externalRoads || [])]; const villages = map.villages || []; const ruralServed = villages.filter((v) => pointPathDistance(v, ordinary) <= 4).length; assert(!villages.length || ruralServed / villages.length >= 0.80, `rural village road coverage is ${(ruralServed / Math.max(1, villages.length)).toFixed(3)}`); assert((map.minorRoads || []).length >= 60, 'published countryside retains a substantial local-road network'); const post = map.transportDebug?.postAdminTransportFinalization || {}; assert((post.finalInterchangeRebuild?.added || 0) >= (post.finalInterchangeRebuild?.target || 0), 'final IC rebuild meets its production target'); assert(post.finalDiscontinuousTransportCleanup, 'final discontinuity cleanup ran'); console.log('All r11.7 terrain-routed transport density regression checks passed.');