80 lines
2.7 KiB
JavaScript
80 lines
2.7 KiB
JavaScript
import { SIZE } from "./mapUtils.js";
|
|
|
|
export function changedCellsSince(before, after, prefectureMask, sea) {
|
|
let changed = 0;
|
|
for (let i = 0; i < SIZE; i++) if (prefectureMask[i] && !sea[i] && before[i] !== after[i]) changed++;
|
|
return changed;
|
|
}
|
|
|
|
export function municipalityAreaById(adminId, prefectureMask, sea) {
|
|
const area = new Map();
|
|
for (let i = 0; i < SIZE; i++) {
|
|
if (!prefectureMask[i] || sea[i] || adminId[i] < 0) continue;
|
|
area.set(adminId[i], (area.get(adminId[i]) || 0) + 1);
|
|
}
|
|
return area;
|
|
}
|
|
|
|
export function maskLandArea(mask, sea) {
|
|
let area = 0;
|
|
for (let i = 0; i < SIZE; i++) if (mask[i] && !sea[i]) area++;
|
|
return area;
|
|
}
|
|
|
|
|
|
export function isProtectedAdminSeed(seed) {
|
|
if (!seed) return false;
|
|
if (seed.seedKind === "capital" || seed.protectedCity?.isPrefecturalCapital) return true;
|
|
if (seed.seedKind === "modernCity" && (seed.protectedCity?.population || seed.population || 0) >= 180000) return true;
|
|
if (seed.seedKind === "port" && seed.portClass === "major") return true;
|
|
if (seed.seedKind === "satelliteCity" && (seed.protectedSatellite?.population || seed.population || 0) >= 60000) return true;
|
|
return false;
|
|
}
|
|
|
|
export function buildSeedLifecycle(adminCenters, adminId, prefectureMask, sea, minArea = 80) {
|
|
const areaById = municipalityAreaById(adminId, prefectureMask, sea);
|
|
const lifecycle = adminCenters.map((center, id) => {
|
|
const protectedSeed = isProtectedAdminSeed(center);
|
|
const area = areaById.get(id) || 0;
|
|
const enoughArea = area >= (protectedSeed ? 28 : minArea);
|
|
return {
|
|
id,
|
|
protected: protectedSeed,
|
|
area,
|
|
state: enoughArea || protectedSeed ? "survived" : "pending",
|
|
};
|
|
});
|
|
return lifecycle;
|
|
}
|
|
|
|
export function activeSeedIds(seedLifecycle) {
|
|
return new Set(seedLifecycle.filter((seed) => seed.state === "survived" || seed.protected).map((seed) => seed.id));
|
|
}
|
|
|
|
export function dominantCompartmentOwners(compartments, adminId) {
|
|
const owner = new Int16Array(compartments.length);
|
|
owner.fill(-1);
|
|
for (const unit of compartments) {
|
|
if (!unit || unit.area === 0) continue;
|
|
const counts = new Map();
|
|
for (const i of unit.cells) {
|
|
const id = adminId[i];
|
|
if (id >= 0) counts.set(id, (counts.get(id) || 0) + 1);
|
|
}
|
|
let bestId = -1, best = -1;
|
|
for (const [id, count] of counts) if (count > best) { best = count; bestId = id; }
|
|
owner[unit.id] = bestId;
|
|
}
|
|
return owner;
|
|
}
|
|
|
|
export function applyCompartmentOwners(adminId, compartments, owner) {
|
|
for (const unit of compartments) {
|
|
if (!unit || unit.area === 0) continue;
|
|
const id = owner[unit.id];
|
|
if (id < 0) continue;
|
|
for (const i of unit.cells) adminId[i] = id;
|
|
}
|
|
}
|
|
|
|
|