refactor: fix burgId issue

This commit is contained in:
max 2022-08-19 23:58:45 +03:00
parent ec6285a7a4
commit bc98757b96
8 changed files with 62 additions and 41 deletions

View file

@ -5,13 +5,28 @@ import {round} from "utils/stringUtils";
export function drawRoutes() {
routes.selectAll("path").remove();
const {cells, burgs} = pack;
const lineGen = d3.line().curve(d3.curveBasis);
const getBurgCoords = (burgId: number): TPoint => {
if (!burgId) throw new Error("burgId must be positive");
const burg = burgs[burgId] as IBurg;
return [burg.x, burg.y];
};
const getPathPoints = (cellIds: number[]): TPoints =>
cellIds.map(cellId => {
const burgId = cells.burg[cellId];
if (burgId) return getBurgCoords(burgId);
return cells.p[cellId];
});
const routePaths: Dict<string[]> = {};
for (const {i, type, cells: routeCells} of pack.routes) {
const points = routeCells.map(cellId => pack.cells.p[cellId]);
const path = round(lineGen(points)!);
const points = getPathPoints(routeCells);
const path = round(lineGen(points)!, 1);
if (!routePaths[type]) routePaths[type] = [];
routePaths[type].push(`<path id="${type}${i}" d="${path}"/>`);

View file

@ -7,7 +7,6 @@ const {Names} = window;
export function createCapitals(
statesNumber: number,
scoredCellIds: UintArray,
burgIds: Uint16Array,
cultures: TCultures,
cells: Pick<IPack["cells"], "p" | "f" | "culture">
) {
@ -15,20 +14,15 @@ export function createCapitals(
const capitalCells = placeCapitals(statesNumber, scoredCellIds, cells.p);
const capitals = capitalCells.map((cellId, index) => {
const id = index + 1;
const capitals = capitalCells.map(cellId => {
const cultureId = cells.culture[cellId];
const nameBase = cultures[cultureId].base;
const name: string = Names.getBaseShort(nameBase);
const featureId = cells.f[cellId];
return {i: id, cell: cellId, culture: cultureId, name, feature: featureId, capital: 1 as Logical};
return {cell: cellId, culture: cultureId, name, feature: featureId, capital: 1 as Logical};
});
for (const {cell, i} of capitals) {
burgIds[cell] = i;
}
TIME && console.timeEnd("createCapitals");
return capitals;
}

View file

@ -17,7 +17,7 @@ export function createStates(capitals: TCapitals, cultures: TCultures) {
const powerInput = getInputNumber("powerInput");
const states = capitals.map((capital, index) => {
const {cell: cellId, culture: cultureId, name: capitalName, i: capitalId} = capital;
const {cell: cellId, culture: cultureId, name: capitalName} = capital;
const id = index + 1;
const name = getStateName(cellId, capitalName, cultureId, cultures);
const color = colors[index];
@ -28,7 +28,7 @@ export function createStates(capitals: TCapitals, cultures: TCultures) {
const shield = COA.getShield(cultureShield, null);
const coa: ICoa = {...COA.generate(null, null, null, type), shield};
return {i: id, name, type, center: cellId, color, expansionism, capital: capitalId, culture: cultureId, coa};
return {i: id, name, type, center: cellId, color, expansionism, capital: id, culture: cultureId, coa};
});
TIME && console.timeEnd("createStates");

View file

@ -8,7 +8,7 @@ import {gauss} from "utils/probabilityUtils";
const {Names} = window;
export function createTowns(
burgIds: Uint16Array,
capitalCells: Map<number, boolean>,
cultures: TCultures,
cells: Pick<IPack["cells"], "p" | "i" | "f" | "s" | "culture">
) {
@ -19,7 +19,7 @@ export function createTowns(
const scores = new Int16Array(cells.s.map(randomizeScore));
// take populated cells without capitals
const scoredCellIds = cells.i.filter(i => scores[i] > 0 && cells.culture[i] && !burgIds[i]);
const scoredCellIds = cells.i.filter(i => scores[i] > 0 && cells.culture[i] && !capitalCells.has(i));
scoredCellIds.sort((a, b) => scores[b] - scores[a]); // sort by randomized suitability score
const townsNumber = getTownsNumber();
@ -27,20 +27,15 @@ export function createTowns(
const townCells = placeTowns(townsNumber, scoredCellIds, cells.p);
const towns = townCells.map((cellId, index) => {
const id = index + 1;
const towns = townCells.map(cellId => {
const cultureId = cells.culture[cellId];
const namesbase = cultures[cultureId].base;
const name: string = Names.getBase(namesbase);
const featureId = cells.f[cellId];
return {i: id, cell: cellId, culture: cultureId, name, feature: featureId, capital: 0 as Logical};
return {cell: cellId, culture: cultureId, name, feature: featureId, capital: 0 as Logical};
});
for (const {cell, i} of towns) {
burgIds[cell] = i;
}
TIME && console.timeEnd("createTowns");
return towns;

View file

@ -12,7 +12,7 @@ type TStates = ReturnType<typeof createStates>;
// growth algorithm to assign cells to states
export function expandStates(
capitals: TCapitals,
capitalCells: Map<number, boolean>,
states: TStates,
features: TPackFeatures,
cells: Pick<IPack["cells"], "c" | "h" | "f" | "t" | "r" | "fl" | "s" | "biome" | "culture">
@ -28,7 +28,10 @@ export function expandStates(
const neutralInput = getInputNumber("neutralInput");
const maxExpansionCost = (cellsNumber / 2) * neutralInput * statesNeutral;
for (const {i: stateId, cell: cellId} of capitals) {
for (const state of states) {
if (state.i === 0) continue;
const {i: stateId, center: cellId} = state as IState;
stateIds[cellId] = stateId;
cost[cellId] = 1;
queue.push({cellId, stateId}, 0);
@ -99,7 +102,7 @@ export function expandStates(
TIME && console.timeEnd("expandStates");
return normalizeStates(stateIds, capitals, cells.c, cells.h);
return normalizeStates(stateIds, capitalCells, cells.c, cells.h);
function isNeutrals(state: Entry<TStates>): state is TNeutrals {
return state.i === 0;
@ -195,11 +198,15 @@ export function expandStates(
}
}
function normalizeStates(stateIds: Uint16Array, capitals: TCapitals, neibCells: number[][], heights: Uint8Array) {
function normalizeStates(
stateIds: Uint16Array,
capitalCells: Map<number, boolean>,
neibCells: number[][],
heights: Uint8Array
) {
TIME && console.time("normalizeStates");
const normalizedStateIds = Uint16Array.from(stateIds);
const capitalCells = capitals.map(capital => capital.cell);
for (let cellId = 0; cellId > heights.length; cellId++) {
if (heights[cellId] < MIN_LAND_HEIGHT) continue;
@ -212,10 +219,10 @@ function normalizeStates(stateIds: Uint16Array, capitals: TCapitals, neibCells:
const buddies = neibs.filter(neib => normalizedStateIds[neib] === normalizedStateIds[cellId]);
if (buddies.length > 2) continue;
const isCapital = capitalCells.includes(cellId);
const isCapital = capitalCells.has(cellId);
if (isCapital) continue;
const isAdjucentToCapital = neibs.some(neib => capitalCells.includes(neib));
const isAdjucentToCapital = neibs.some(neib => capitalCells.has(neib));
if (isAdjucentToCapital) continue;
// change cells's state

View file

@ -32,13 +32,14 @@ export function generateBurgsAndStates(
};
}
const burgIds = new Uint16Array(cellsNumber);
const capitals = createCapitals(statesNumber, scoredCellIds, burgIds, cultures, pick(cells, "p", "f", "culture"));
const capitals = createCapitals(statesNumber, scoredCellIds, cultures, pick(cells, "p", "f", "culture"));
const capitalCells = new Map(capitals.map(({cell}) => [cell, true]));
const states = createStates(capitals, cultures);
const towns = createTowns(burgIds, cultures, pick(cells, "p", "i", "f", "s", "culture"));
const towns = createTowns(capitalCells, cultures, pick(cells, "p", "i", "f", "s", "culture"));
const stateIds = expandStates(
capitals,
capitalCells,
states,
features,
pick(cells, "c", "h", "f", "t", "r", "fl", "s", "biome", "culture")
@ -57,6 +58,8 @@ export function generateBurgsAndStates(
pick(cells, "v", "p", "g", "h", "f", "haven", "harbor", "s", "biome", "fl", "r")
);
const burgIds = assignBurgIds(burgs);
return {burgIds, stateIds, burgs, states};
function getScoredCellIds() {
@ -85,4 +88,15 @@ export function generateBurgsAndStates(
return requestedStatesNumber;
}
function assignBurgIds(burgs: TBurgs) {
const burgIds = new Uint16Array(cellsNumber);
for (let i = 1; i < burgs.length; i++) {
const {cell} = burgs[i] as IBurg;
burgIds[cell] = i;
}
return burgIds;
}
}

View file

@ -29,7 +29,7 @@ export function specifyBurgs(
): TBurgs {
TIME && console.time("specifyBurgs");
const burgs = [...capitals, ...towns].map(burgData => {
const burgs = [...capitals, ...towns].map((burgData, index) => {
const {cell, culture, capital} = burgData;
const state = stateIds[cell];
@ -40,7 +40,7 @@ export function specifyBurgs(
const type = defineType(cell, port, population);
const coa: ICoa = defineEmblem(state, culture, port, capital, type, cultures, states);
const burg: IBurg = {...burgData, state, port, population, x, y, type, coa};
const burg: IBurg = {i: index + 1, ...burgData, state, port, population, x, y, type, coa};
return burg;
});

View file

@ -1,13 +1,9 @@
import {ERROR} from "../config/logging";
import {rn} from "./numberUtils";
// round numbers in string to d decimals
export function round(str: string, d = 1) {
if (!str) {
ERROR && console.error("Path is empty", str);
return "";
}
return str.replace(/[\d\.-][\d\.e-]*/g, n => String(rn(+n, d)));
export function round(str: string, decimals = 1) {
if (!str) throw new Error("Path is empty");
return str.replace(/[\d\.-][\d\.e-]*/g, n => String(rn(+n, decimals)));
}
// return string with 1st char capitalized