refactor: generateCoreProvinces

This commit is contained in:
Azgaar 2022-09-06 23:16:21 +03:00
parent 2b61ac6a0f
commit fe2f8428ad
11 changed files with 129 additions and 19 deletions

View file

@ -15,6 +15,7 @@
"@rollup/plugin-node-resolve": "^13.3.0",
"@rollup/plugin-replace": "^4.0.0",
"@types/d3": "^5.9.0",
"@types/d3-array": "^3.0.3",
"@types/delaunator": "^5.0.0",
"@types/jquery": "^3.5.14",
"@types/jqueryui": "^1.12.16",
@ -35,6 +36,7 @@
},
"dependencies": {
"d3": "5.8.0",
"d3-array": "^3.2.0",
"delaunator": "^5.0.0",
"flatqueue": "^2.0.3",
"lineclip": "^1.1.5",

View file

@ -40,7 +40,7 @@ export function defineStateForm(
const generic = {Monarchy: 25, Republic: 2, Union: 1};
const naval = {Monarchy: 6, Republic: 2, Union: 1};
function defineForm(type: TCultureType, areaTier: AreaTiers) {
function defineForm(type: TCultureType, areaTier: AreaTiers): TStateForm {
const isAnarchy = P((1 - areaTier / 5) / 100); // [1% - 0.2%] chance
if (isAnarchy) return "Anarchy";

View file

@ -143,7 +143,7 @@ export function createPack(grid: IGrid): IPack {
}
});
const {provinceIds, provinces} = generateProvinces();
const {provinceIds, provinces} = generateProvinces(states, burgs, cultures, {i: cells.i});
// BurgsAndStates.generateProvinces();
// BurgsAndStates.defineBurgFeatures();

View file

@ -0,0 +1,8 @@
export const provinceForms = {
Monarchy: {County: 22, Earldom: 6, Shire: 2, Landgrave: 2, Margrave: 2, Barony: 2, Captaincy: 1, Seneschalty: 1},
Republic: {Province: 6, Department: 2, Governorate: 2, District: 1, Canton: 1, Prefecture: 1},
Theocracy: {Parish: 3, Deanery: 1},
Union: {Province: 1, State: 1, Canton: 1, Republic: 1, County: 1, Council: 1},
Anarchy: {Council: 1, Commune: 1, Community: 1, Tribe: 1},
Wild: {Territory: 10, Land: 5, Region: 2, Tribe: 1, Clan: 1, Dependency: 1, Area: 1}
};

View file

@ -0,0 +1,9 @@
import {gauss} from "utils/probabilityUtils";
export function expandProvinces(percentage: number, cells: Pick<IPack["cells"], "i">) {
const provinceIds = new Uint16Array(cells.i.length);
const maxGrowth = percentage === 100 ? 1000 : gauss(20, 5, 5, 100) * percentage ** 0.5;
return provinceIds;
}

View file

@ -0,0 +1,67 @@
import {group} from "d3-array";
import {brighter, getMixedColor} from "utils/colorUtils";
import {gauss, P, rw} from "utils/probabilityUtils";
import {isBurg, isState} from "utils/typeUtils";
import {provinceForms} from "./config";
const {COA, Names} = window;
export function generateCoreProvinces(states: TStates, burgs: TBurgs, cultures: TCultures, percentage: number) {
const provinces = [] as IProvince[];
const validBurgs = burgs.filter(isBurg);
const burgsToStateMap = group(validBurgs, (burg: IBurg) => burg.state);
states.filter(isState).forEach(state => {
const stateBurgs = burgsToStateMap.get(state.i);
if (!stateBurgs || stateBurgs.length < 2) return; // at least 2 provinces are required
stateBurgs
.sort((a, b) => b.population * gauss(1, 0.2, 0.5, 1.5, 3) - a.population)
.sort((a, b) => b.capital - a.capital);
const provincesNumber = Math.max(Math.ceil((stateBurgs.length * percentage) / 100), 2);
const formsPool: Dict<number> = structuredClone(provinceForms[state.form]);
for (let i = 0; i < provincesNumber; i++) {
const {i: burg, cell: center, culture: cultureId, coa: burgEmblem, name: burgName, type} = stateBurgs[i];
const nameByBurg = P(0.5);
const name = nameByBurg ? burgName : generateName(cultureId, cultures);
3;
const formName = rw(formsPool);
formsPool[formName] += 10; // increase chance to get the same form again
const fullName = name + " " + formName;
const color = brighter(getMixedColor(state.color, 0.2), 0.3);
const coa = generateEmblem(nameByBurg, burgEmblem, type, cultures, cultureId, state);
provinces.push({i: provinces.length, name, formName, center, burg, state: state.i, fullName, color, coa});
}
});
return provinces;
}
function generateName(cultureId: number, cultures: TCultures) {
const base = cultures[cultureId].base;
return Names.getState(Names.getBaseShort(base), base);
}
function generateEmblem(
nameByBurg: boolean,
burgEmblem: ICoa | "string",
type: TCultureType,
cultures: TCultures,
cultureId: number,
state: IState
) {
const kinship = nameByBurg ? 0.8 : 0.4;
const coa: ICoa = COA.generate(burgEmblem, kinship, null, type);
const cultureShield = cultures[cultureId].shield;
const stateShield = (state.coa as ICoa)?.shield;
coa.shield = COA.getShield(cultureShield, stateShield);
return coa;
}

View file

@ -1,26 +1,24 @@
import {TIME} from "config/logging";
import {getInputNumber} from "utils/nodeUtils";
import {gauss} from "utils/probabilityUtils";
import {expandProvinces} from "./expandProvinces";
import {generateCoreProvinces} from "./generateCoreProvinces";
const forms = {
Monarchy: {County: 22, Earldom: 6, Shire: 2, Landgrave: 2, Margrave: 2, Barony: 2, Captaincy: 1, Seneschalty: 1},
Republic: {Province: 6, Department: 2, Governorate: 2, District: 1, Canton: 1, Prefecture: 1},
Theocracy: {Parish: 3, Deanery: 1},
Union: {Province: 1, State: 1, Canton: 1, Republic: 1, County: 1, Council: 1},
Anarchy: {Council: 1, Commune: 1, Community: 1, Tribe: 1},
Wild: {Territory: 10, Land: 5, Region: 2, Tribe: 1, Clan: 1, Dependency: 1, Area: 1}
};
export function generateProvinces(states: TStates, cells: Pick<IPack["cells"], "i">) {
export function generateProvinces(
states: TStates,
burgs: TBurgs,
cultures: TCultures,
cells: Pick<IPack["cells"], "i">
) {
TIME && console.time("generateProvinces");
const provinceIds = new Uint16Array(cells.i.length);
const provinces = [] as TProvinces;
const percentage = getInputNumber("provincesInput");
if (states.length < 2 || percentage === 0) return {provinceIds, provinces};
if (states.length < 2 || percentage === 0)
return {provinceIds: new Uint16Array(cells.i.length), provinces: [] as TProvinces[]};
const maxGrowth = percentage === 100 ? 1000 : gauss(20, 5, 5, 100) * percentage ** 0.5;
const coreProvinces = generateCoreProvinces(states, burgs, cultures, percentage);
const provinceIds = expandProvinces(percentage, cells);
const provinces = [...coreProvinces];
TIME && console.timeEnd("generateProvinces");
return {provinceIds, provinces};

View file

@ -3,6 +3,7 @@ interface IBurg {
name: string;
feature: number;
state: number;
culture: number;
cell: number;
x: number;
y: number;

View file

@ -1,7 +1,13 @@
interface IProvince {
i: number;
name: string;
burg: number;
formName: string;
fullName: string;
color: Hex | CssUrls;
state: number;
center: number;
coa: ICoa | string;
removed?: boolean;
}

View file

@ -7,7 +7,7 @@ interface IState {
type: TCultureType;
culture: number;
expansionism: number;
form: string;
form: TStateForm;
formName: string;
fullName: string;
coa: ICoa | string;
@ -38,6 +38,8 @@ interface ICoa {
t1: string;
}
type TStateForm = "Monarchy" | "Republic" | "Theocracy" | "Union" | "Anarchy";
type TRelation =
| "Ally"
| "Friendly"

View file

@ -155,6 +155,11 @@
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-1.2.9.tgz#c7dc78992cd8ca5c850243a265fd257ea56df1fa"
integrity sha512-E/7RgPr2ylT5dWG0CswMi9NpFcjIEDqLcUSBgNHe/EMahfqYaTx4zhcggG3khqoEB/leY4Vl6nTSbwLUPjXceA==
"@types/d3-array@^3.0.3":
version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.3.tgz#87d990bf504d14ad6b16766979d04e943c046dac"
integrity sha512-Reoy+pKnvsksN0lQUlcH6dOGjRZ/3WRwXR//m+/8lt1BXeI4xyaUZoqULNjyXXRuh0Mj4LNpkCvhUpQlY3X5xQ==
"@types/d3-axis@^1":
version "1.0.16"
resolved "https://registry.yarnpkg.com/@types/d3-axis/-/d3-axis-1.0.16.tgz#93d7a28795c2f8b0e2fd550fcc4d29b7f174e693"
@ -738,6 +743,13 @@ d3-array@1, d3-array@^1.1.1, d3-array@^1.2.0:
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.2.4.tgz#635ce4d5eea759f6f605863dbcfc30edc737f71f"
integrity sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==
d3-array@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.0.tgz#15bf96cd9b7333e02eb8de8053d78962eafcff14"
integrity sha512-3yXFQo0oG3QCxbF06rMPFyGRMGJNS7NvsV1+2joOjbBE+9xvWQ8+GcMJAjRCzw06zQ3/arXeJgbPYcjUCuC+3g==
dependencies:
internmap "1 - 2"
d3-axis@1:
version "1.0.12"
resolved "https://registry.yarnpkg.com/d3-axis/-/d3-axis-1.0.12.tgz#cdf20ba210cfbb43795af33756886fb3638daac9"
@ -1469,6 +1481,11 @@ inherits@2, inherits@^2.0.3, inherits@~2.0.3:
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
"internmap@1 - 2":
version "2.0.3"
resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009"
integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==
is-builtin-module@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.1.0.tgz#6fdb24313b1c03b75f8b9711c0feb8c30b903b00"