From eb1b52100cc054f7ddbeb865e8b001828b07704d Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Sun, 17 Mar 2024 14:01:52 +0100 Subject: Parse layout and generate map data. --- tools/parse-layout.js | 235 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 223 insertions(+), 12 deletions(-) (limited to 'tools/parse-layout.js') diff --git a/tools/parse-layout.js b/tools/parse-layout.js index 5219705..e3a76fd 100644 --- a/tools/parse-layout.js +++ b/tools/parse-layout.js @@ -2,7 +2,7 @@ const fs = require("fs") let points = {} let rects = {} -let edges = [] +let edges = {} let mode, name, x, y, w, h, cx, cy, rx, ry, x2, y2 function add_point(x, y) { @@ -19,9 +19,16 @@ function add_rect(x, y, w, h) { rects[name] = [ [x,y,x+w,y+h] ] } +function add_edge(x1, y1, x2, y2) { + if (name in edges) + edges[name].push({x1,y1,x2,y2}) + else + edges[name] = [ {x1,y1,x2,y2} ] +} + function flush() { if (mode === 'path') { - edges.push([ x, y, x2, y2 ]) + add_edge(x, y, x2, y2) } if (mode === 'rect') { if (name.startsWith("$")) @@ -180,6 +187,21 @@ function find_closest_node(list, x, y) { return [ nn, nd ] } +function find_closest_city(x, y) { + let nd = Infinity, nn = -1 + + for (let i = 0; i < cities.length; ++i) { + let n = cities[i] + let d = Math.hypot(n.x - x, n.y - y) + if (d < nd) { + nd = d + nn = i + } + } + + return nn +} + function find_enclosing_rect(list, x, y) { for (let [x1, y1, x2, y2] of list) { if (x >= x1 && x <= x2) @@ -189,36 +211,225 @@ function find_enclosing_rect(list, x, y) { return false } +const FLANDERS = "Flanders" +const BOHEMIA = "Bohemia" + +const CLUBS = "clubs" +const HEARTS = "hearts" +const SPADES = "spades" +const DIAMONDS = "diamonds" + +const FRANCE = "France" +const BAVARIA = "Bavaria" +const PRUSSIA = "Prussia" +const SAXONY = "Saxony" +const AUSTRIA = "Austria" +const AUSTRIAN_NETHERLANDS = "Austrian Netherlands" +const HRE = "Holy Roman Empire" +const NETHERLANDS = "Netherlands" +const SILESIA = "Silesia" +const POLAND = "Poland" + +const PRAGMATIC_ARMY = "Pragmatic Army" + // FIND and label all points! let all_labels = labels.slice() -let out = {} +let cities = [] for (let key in points) { - out = {} for (let [x, y] of points[key]) { let [ node, dist ] = find_closest_node(labels, x, y) if (dist > 10) { console.log(key,x,y, dist) } if (node) { - if (node.name in out) - console.log("DUPLICATE", node.name, x, y, out[node.name]) labels = labels.filter(x => x !== node) let suit = "UNKNOWN" + if (find_enclosing_rect(rects.$CLUBS, x, y)) - suit = "clubs" + suit = CLUBS else if (find_enclosing_rect(rects.$HEARTS, x, y)) - suit = "hearts" + suit = HEARTS else if (find_enclosing_rect(rects.$DIAMONDS, x, y)) - suit = "diamonds" + suit = DIAMONDS else if (find_enclosing_rect(rects.$SPADES, x, y)) - suit = "spades" + suit = SPADES else console.log("NOT ASSIGNED SUIT", x, y) - out[node.name] = [x, y, dist, suit] + + let map = "UNKNOWN" + let country = "UNKNOWN" + if (find_enclosing_rect(rects.$HRE_W, x, y)) { + map = FLANDERS + country = HRE + } + else if (find_enclosing_rect(rects.$HRE_E, x, y)) { + map = BOHEMIA + country = HRE + } + else if (find_enclosing_rect(rects.$Austria_W, x, y)) { + map = FLANDERS + country = AUSTRIA + } + else if (find_enclosing_rect(rects.$Austria_E, x, y)) { + map = BOHEMIA + country = AUSTRIA + } + else if (find_enclosing_rect(rects.$Bavaria, x, y)) { + map = BOHEMIA + country = BAVARIA + } + else if (find_enclosing_rect(rects.$Saxony, x, y)) { + map = BOHEMIA + country = SAXONY + } + else if (find_enclosing_rect(rects.$Silesia, x, y)) { + map = BOHEMIA + country = SILESIA + } + else if (find_enclosing_rect(rects.$Poland, x, y)) { + map = BOHEMIA + country = POLAND + } + else if (find_enclosing_rect(rects.$Prussia, x, y)) { + map = BOHEMIA + country = PRUSSIA + } + else if (find_enclosing_rect(rects.$Netherlands, x, y)) { + map = FLANDERS + country = NETHERLANDS + } + else if (find_enclosing_rect(rects.$France, x, y)) { + map = FLANDERS + country = FRANCE + } + + if (country === "UNKNOWN") + console.log("no country:", node) + + cities.push({ + name: node.name, + map, + country, + suit, + type: key, + x: Math.round(x), + y: Math.round(y), + major_roads: [], + roads: [], + }) } else { let [ dupname, dupdist ] = find_closest_node(all_labels, x, y) - console.log("ALREADY USED", dupname, dupdist, x, y, "OLD", out[dupname]) + console.log("ALREADY USED", dupname, dupdist, x, y) } } } +cities.sort((a,b) => { + if (a.map < b.map) return 1 + if (a.map > b.map) return -1 + if (a.country < b.country) return -1 + if (a.country > b.country) return 1 + if (a.suit < b.suit) return -1 + if (a.suit > b.suit) return 1 + if (a.type === "major_fortress" && b.type !== "major_fortress") return -1 + if (a.type !== "major_fortress" && b.type === "major_fortress") return 1 + if (a.type === "minor_fortress" && b.type !== "minor_fortress") return -1 + if (a.type !== "minor_fortress" && b.type === "minor_fortress") return 1 + if (a.name < b.name) return -1 + if (a.name > b.name) return 1 + return b.y - a.y +}) + +for (let e of edges.major_road) { + let a = find_closest_city(e.x1, e.y1) + let b = find_closest_city(e.x2, e.y2) + cities[a].major_roads.push(b) + cities[b].major_roads.push(a) +} + +for (let e of edges.road) { + let a = find_closest_city(e.x1, e.y1) + let b = find_closest_city(e.x2, e.y2) + cities[a].roads.push(b) + cities[b].roads.push(a) +} + +let arrays = { + name: [], + // map: [], + // country: [], + // suit: [], + // type: [], + x: [], + y: [], + major_roads: [], + roads: [], +} + +let sets = { + type: { + major_fortress: [], + minor_fortress: [], + city: [], + }, + suit: { + clubs: [], + diamonds: [], + hearts: [], + spades: [], + }, + map: { + Flanders: [], + Bohemia: [], + }, + country: { + Austria: [], + Bavaria: [], + France: [], + Netherlands: [], + Poland: [], + Prussia: [], + Saxony: [], + Silesia: [], + "Holy Roman Empire": [], + }, +} + +for (let i = 0; i < cities.length; ++i) { + let city = cities[i] + for (let key in city) { + if (arrays[key]) + arrays[key].push(city[key]) + if (sets[key]) + sets[key][city[key]].push(i) + } +} + +function map_to_range(x) { + let pairs = [] + let a = 0, b = 1 + for (; b < x.length; ++b) { + if (x[b-1] + 1 === x[b]) + continue + pairs.push([x[a],x[b-1]]) + a = b + } + pairs.push([x[a],x[b-1]]) + return pairs +} + +function remap_to_range(obj) { + for (let key in obj) + obj[key] = map_to_range(obj[key]) +} + +remap_to_range(sets.map) +remap_to_range(sets.suit) +remap_to_range(sets.country) + +delete sets.type.city + +sets.cities = arrays + +console.log("const data = " + JSON.stringify(sets)) +console.log("if (typeof module === 'object') module.exports = data") -- cgit v1.2.3