diff --git a/modules/burgs-and-states.js b/modules/burgs-and-states.js index d04ee699..2213edac 100644 --- a/modules/burgs-and-states.js +++ b/modules/burgs-and-states.js @@ -287,25 +287,28 @@ // growth algorithm to assign cells to states like we did for cultures const expandStates = function() { TIME && console.time("expandStates"); - const cells = pack.cells, states = pack.states, cultures = pack.cultures, burgs = pack.burgs; + const {cells, states, cultures, burgs} = pack; - cells.state = new Uint16Array(cells.i.length); // cell state + cells.state = new Uint16Array(cells.i.length); const queue = new PriorityQueue({comparator: (a, b) => a.p - b.p}); const cost = []; - states.filter(s => s.i && !s.removed).forEach(function(s) { - cells.state[burgs[s.capital].cell] = s.i; - const b = cells.biome[cultures[s.culture].center]; // native biome + const neutral = cells.i.length / 5000 * 2500 * neutralInput.value * statesNeutral.value; // limit cost for state growth + + states.filter(s => s.i && !s.removed).forEach(s => { + const capitalCell = burgs[s.capital].cell; + cells.state[capitalCell] = s.i; + const cultureCenter = cultures[s.culture].center; + const b = cells.biome[cultureCenter]; // state native biome queue.queue({e:s.center, p:0, s:s.i, b}); cost[s.center] = 1; }); - const neutral = cells.i.length / 5000 * 2500 * neutralInput.value * statesNeutral.value; // limit cost for state growth while (queue.length) { - const next = queue.dequeue(), n = next.e, p = next.p, s = next.s, b = next.b; - const type = states[s].type; - const culture = states[s].culture; + const next = queue.dequeue(); + const {e, p, s, b} = next; + const {type, culture} = states[s]; - cells.c[n].forEach(function(e) { + cells.c[e].forEach(e => { if (cells.state[e] && e === states[cells.state[e]].center) return; // do not overwrite capital cells const cultureCost = culture === cells.culture[e] ? -9 : 100; diff --git a/modules/cultures-generator.js b/modules/cultures-generator.js index 6901b7f7..9ef56fe1 100644 --- a/modules/cultures-generator.js +++ b/modules/cultures-generator.js @@ -43,6 +43,7 @@ const colors = getColors(count); const emblemShape = document.getElementById("emblemShape").value; + const codes = []; cultures.forEach(function(c, i) { const cell = c.center = placeCenter(c.sort ? c.sort : (i) => cells.s[i]); centers.add(cells.p[cell]); @@ -53,7 +54,8 @@ c.type = defineCultureType(cell); c.expansionism = defineCultureExpansionism(c.type); c.origin = 0; - c.code = getCode(c.name); + c.code = abbreviate(c.name, codes); + codes.push(c.code); cells.culture[cell] = i+1; if (emblemShape === "random") c.shield = getRandomShield(); }); @@ -122,20 +124,10 @@ TIME && console.timeEnd('generateCultures'); } - // assign a unique two-letters code (abbreviation) - function getCode(name) { - name = name.replace(/[()]/g, ""); - const words = name.split(" "), letters = words.join(""); - let code = words.length === 2 ? words[0][0]+words[1][0] : letters.slice(0,2); - for (let i=1; i < letters.length-1 && pack.cultures.some(c => c.code === code); i++) { - code = letters[0] + letters[i].toUpperCase(); - } - return code; - } - const add = function(center) { const defaultCultures = getDefault(); let culture, base, name; + if (pack.cultures.length < defaultCultures.length) { // add one of the default cultures culture = pack.cultures.length; @@ -147,7 +139,7 @@ name = Names.getCulture(culture, 5, 8, ""); base = pack.cultures[culture].base; } - const code = getCode(name); + const code = abbreviate(name, pack.cultures.map(c => c.code)); const i = pack.cultures.length; const color = d3.color(d3.scaleSequential(d3.interpolateRainbow)(Math.random())).hex(); diff --git a/modules/religions-generator.js b/modules/religions-generator.js index 1563f966..1e2535dd 100644 --- a/modules/religions-generator.js +++ b/modules/religions-generator.js @@ -71,7 +71,7 @@ }); if (religionsInput.value == 0 || pack.cultures.length < 2) { - religions.filter(r => r.i).forEach(r => r.code = getCode(r.name)); + religions.filter(r => r.i).forEach(r => r.code = abbreviate(r.name)); return; } @@ -182,7 +182,7 @@ if (type === "Organized") [name, expansion] = getReligionName(form, deity, center) else {name = getCultName(form, center); expansion = "global";} const formName = type === "Heresy" ? religions[r].form : form; - const code = getCode(name); + const code = abbreviate(name, religions.map(r => r.code)); religions.push({i, name, color, culture, type, form:formName, deity, expansion, expansionism:0, center, cells:0, area:0, rural:0, urban:0, origin:r, code}); cells.religion[center] = i; } @@ -267,9 +267,9 @@ function checkCenters() { const cells = pack.cells, religions = pack.religions; + const codes = religions.map(r => r.code); religions.filter(r => r.i).forEach(r => { - // generate religion code (abbreviation) - r.code = getCode(r.name); + r.code = abbreviate(r.name, codes); // move religion center if it's not within religion area after expansion if (cells.religion[r.center] === r.i) return; // in area @@ -290,17 +290,6 @@ TIME && console.timeEnd('updateCulturesForReligions'); } - // assign a unique two-letters code (abbreviation) - function getCode(rawName) { - const name = rawName.replace("Old ", ""); // remove Old prefix - const words = name.split(" "), letters = words.join(""); - let code = words.length === 2 ? words[0][0]+words[1][0] : letters.slice(0,2); - for (let i=1; i < letters.length-1 && pack.religions.some(r => r.code === code); i++) { - code = letters[0] + letters[i].toUpperCase(); - } - return code; - } - // get supreme deity name const getDeityName = function(culture) { if (culture === undefined) {ERROR && console.error("Please define a culture"); return;} diff --git a/modules/ui/cultures-editor.js b/modules/ui/cultures-editor.js index 67e4618c..ecb1060e 100644 --- a/modules/ui/cultures-editor.js +++ b/modules/ui/cultures-editor.js @@ -216,6 +216,7 @@ function editCultures() { const culture = +this.parentNode.dataset.id; this.parentNode.dataset.name = this.value; pack.cultures[culture].name = this.value; + pack.cultures[culture].code = abbreviate(this.value, pack.cultures.map(c => c.code)); } function cultureChangeExpansionism() { diff --git a/modules/ui/religions-editor.js b/modules/ui/religions-editor.js index 704ff531..8161f15e 100644 --- a/modules/ui/religions-editor.js +++ b/modules/ui/religions-editor.js @@ -200,6 +200,7 @@ function editReligions() { const religion = +this.parentNode.dataset.id; this.parentNode.dataset.name = this.value; pack.religions[religion].name = this.value; + pack.religions[religion].code = abbreviate(this.value, pack.religions.map(c => c.code)); } function religionChangeType() { diff --git a/modules/utils.js b/modules/utils.js index 623452c0..4ab91e3f 100644 --- a/modules/utils.js +++ b/modules/utils.js @@ -447,6 +447,19 @@ function getAdjective(string) { // get ordinal out of integer: 1 => 1st const nth = n => n+(["st","nd","rd"][((n+90)%100-10)%10-1]||"th"); +// get two-letters code (abbreviation) from string +function abbreviate(name, restricted = []) { + const parsed = name.replace("Old ", "O ").replace(/[()]/g, ""); // remove Old prefix and parentheses + const words = parsed.split(" "); + const letters = words.join(""); + + let code = words.length === 2 ? words[0][0]+words[1][0] : letters.slice(0,2); + for (let i = 1; i < letters.length-1 && restricted.includes(code); i++) { + code = letters[0] + letters[i].toUpperCase(); + } + return code; +} + // conjunct array: [A,B,C] => "A, B and C" function list(array) { if (!Intl.ListFormat) return array.join(", ");