const fs = require("fs") let points = {} let rects = {} let edges = {} let mode, name, x, y, w, h, cx, cy, rx, ry, x2, y2 function add_point(x, y) { if (name in points) points[name].push([x,y]) else points[name] = [ [x,y] ] } function add_rect(x, y, w, h) { if (name in rects) rects[name].push([x,y,x+w,y+h]) else 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') { add_edge(x, y, x2, y2) } if (mode === 'rect') { if (name.startsWith("$")) add_rect(x, y, w, h) else add_point( x + w/2, y + h/2 ) } if (mode === 'circle') { add_point( cx, cy ) } x = y = x2 = y2 = w = h = cx = cy = rx = ry = 0 } function parse_path_data(path) { let cx = 0 let cy = 0 let abs = 0 for (let i = 0; i < path.length;) { switch (path[i]) { case 'M': x = cx = Number(path[i+1]) y = cy = Number(path[i+2]) i += 3 abs = true break case 'm': x = cx = cx + Number(path[i+1]) y = cy = cy + Number(path[i+2]) i += 3 abs = false break case 'C': x2 = cx = Number(path[i+5]) y2 = cy = Number(path[i+6]) i += 7 abs = true break case 'L': i += 1 abs = true break case 'H': x2 = cx = Number(path[i+1]) i += 2 abs = true break case 'V': y2 = cy = Number(path[i+1]) i += 2 abs = true break case 'c': x2 = cx = cx + Number(path[i+5]) y2 = cy = cy + Number(path[i+6]) i += 7 break case 'l': i += 1 abs = false break case 'h': x2 = cx = cx + Number(path[i+1]) i += 2 abs = false break case 'v': y2 = cy = cy + Number(path[i+1]) i += 2 abs = false break default: if (abs) { x2 = cx = Number(path[i+0]) y2 = cy = Number(path[i+1]) } else { x2 = cx = cx + Number(path[i+0]) y2 = cy = cy + Number(path[i+1]) } i += 2 break } } } for (let line of fs.readFileSync("tools/layout.svg", "utf-8").split("\n")) { line = line.trim() if (line.startsWith("([^<]*)= x1 && x <= x2) if (y >= y1 && y <= y2) return true } 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 cities = [] for (let key in points) { 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) { labels = labels.filter(x => x !== node) let suit = "UNKNOWN" if (find_enclosing_rect(rects.$CLUBS, x, y)) suit = CLUBS else if (find_enclosing_rect(rects.$HEARTS, x, y)) suit = HEARTS else if (find_enclosing_rect(rects.$DIAMONDS, x, y)) suit = DIAMONDS else if (find_enclosing_rect(rects.$SPADES, x, y)) suit = SPADES else console.log("NOT ASSIGNED SUIT", x, y) 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) } } } 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")