summaryrefslogtreecommitdiff
path: root/tools/parse-layout-old.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/parse-layout-old.js')
-rw-r--r--tools/parse-layout-old.js466
1 files changed, 466 insertions, 0 deletions
diff --git a/tools/parse-layout-old.js b/tools/parse-layout-old.js
new file mode 100644
index 0000000..b382849
--- /dev/null
+++ b/tools/parse-layout-old.js
@@ -0,0 +1,466 @@
+"use strict"
+
+/* COMMON PARSING */
+
+const fs = require("fs")
+
+let points = {}
+let circles = {}
+let rects = {}
+let edges = {}
+let labels = []
+
+let mode, name, x, y, w, h, cx, cy, rx, ry, x2, y2
+
+function array_insert(array, index, item) {
+ for (let i = array.length; i > index; --i)
+ array[i] = array[i - 1]
+ array[index] = item
+}
+
+function set_add(set, item) {
+ let a = 0
+ let b = set.length - 1
+ while (a <= b) {
+ let m = (a + b) >> 1
+ let x = set[m]
+ if (item < x)
+ b = m - 1
+ else if (item > x)
+ a = m + 1
+ else
+ return
+ }
+ array_insert(set, a, item)
+}
+
+function add_point(x, y) {
+ if (!(name in points))
+ points[name] = []
+ points[name].push({x,y})
+}
+
+function add_circle(cx, cy, rx, ry) {
+ if (!(name in circles))
+ circles[name] = []
+ circles[name].push({x:cx-rx,y:cy-ry,w:rx*2,h:ry*2})
+}
+
+function add_rect(x, y, w, h) {
+ if (!(name in rects))
+ rects[name] = []
+ rects[name].push({x,y,w,h})
+}
+
+function add_edge(x1, y1, x2, y2) {
+ if (!(name in edges))
+ edges[name] = []
+ edges[name].push({x1,y1,x2,y2})
+}
+
+function flush() {
+ if (mode === 'path') {
+ add_edge(x, y, x2, y2)
+ }
+ if (mode === 'rect') {
+ add_rect(x, y, w, h)
+ add_point(x + w/2, y + h/2)
+ }
+ if (mode === 'circle') {
+ add_circle(cx, cy, rx, ry)
+ 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':
+ x2 = x = cx = Number(path[i+1])
+ y2 = y = cy = Number(path[i+2])
+ i += 3
+ abs = true
+ break
+ case 'm':
+ x2 = x = cx = cx + Number(path[i+1])
+ y2 = 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
+ abs = false
+ 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("<rect")) {
+ flush()
+ mode = "rect"
+ x = y = w = h = 0
+ }
+ else if (line.startsWith("<ellipse") || line.startsWith("<circle")) {
+ flush()
+ mode = "circle"
+ cx = cy = rx = ry = 0
+ }
+ else if (line.startsWith("<path")) {
+ flush()
+ mode = "path"
+ }
+ else if (line.startsWith("<g")) {
+ flush()
+ mode = "g"
+ }
+ else if (line.startsWith('x="'))
+ x = (Number(line.split('"')[1]))
+ else if (line.startsWith('y="'))
+ y = (Number(line.split('"')[1]))
+ else if (line.startsWith('width="'))
+ w = (Number(line.split('"')[1]))
+ else if (line.startsWith('height="'))
+ h = (Number(line.split('"')[1]))
+ else if (line.startsWith('cx="'))
+ cx = (Number(line.split('"')[1]))
+ else if (line.startsWith('cy="'))
+ cy = (Number(line.split('"')[1]))
+ else if (line.startsWith('r="'))
+ rx = ry = (Number(line.split('"')[1]))
+ else if (line.startsWith('rx="'))
+ rx = (Number(line.split('"')[1]))
+ else if (line.startsWith('ry="'))
+ ry = (Number(line.split('"')[1]))
+ else if (line.startsWith('inkscape:label="') && mode === "g")
+ name = line.split('"')[1]
+ else if (line.startsWith('d="'))
+ parse_path_data(line.split('"')[1].split(/[ ,]/))
+ if (line.includes("</tspan>")) {
+ let name = line.replace(/^[^>]*>/, "").replace(/<\/tspan.*/, "")
+ labels.push({x, y, name})
+ }
+}
+
+flush()
+
+function find_closest_label(x, y) {
+ let nd = Infinity, nn = null
+
+ for (let n of labels) {
+ let d = Math.hypot(n.x - x, n.y - y)
+ if (d < nd) {
+ nd = d
+ nn = n
+ }
+ }
+
+ if (!nn) {
+ console.log("NOT FOUND", x, y)
+ return null
+ }
+
+ if (nd > 50) {
+ console.log("NO LABEL", x, y, nd)
+ return null
+ }
+
+ return nn.name
+}
+
+function find_closest_node(nodes, x, y) {
+ let nd = Infinity, nn = -1
+
+ for (let i = 0; i < nodes.length; ++i) {
+ let n = nodes[i]
+ let d = Math.hypot(n.x - x, n.y - y)
+ if (d < nd) {
+ nd = d
+ nn = i
+ }
+ }
+
+ if (nd > 100)
+ return -1
+
+ return nn
+}
+
+function label_boxes(top) {
+ for (let key in top) {
+ console.log("BOX", key)
+ for (let item of top[key])
+ item.name = find_closest_label(item.x + item.w/2, item.y + item.h/2)
+ }
+}
+
+function label_points(top) {
+ for (let key in top) {
+ console.log("POINT", key)
+ for (let item of top[key])
+ item.name = find_closest_label(item.x, item.y)
+ }
+}
+
+label_boxes(rects)
+label_boxes(circles)
+label_points(points)
+
+function connect_edge_2way(node_list, edge_name) {
+ console.log("EDGE", edge_name)
+ for (let e of edges[edge_name]) {
+ let a = find_closest_node(node_list, e.x1, e.y1)
+ let b = find_closest_node(node_list, e.x2, e.y2)
+ if (a < 0 || b < 0)
+ console.log("CANNOT FIND EDGE", e, node_list[a], node_list[b])
+ if (!node_list[a][edge_name])
+ node_list[a][edge_name] = []
+ if (!node_list[b][edge_name])
+ node_list[b][edge_name] = []
+ set_add(node_list[a][edge_name], b)
+ set_add(node_list[b][edge_name], a)
+ }
+}
+
+function connect_edge_1way(a_list, b_list, edge_name, prop_name) {
+ console.log("EDGE", edge_name)
+ for (let e of edges[edge_name]) {
+ let a1 = find_closest_node(a_list, e.x1, e.y1)
+ let a2 = find_closest_node(a_list, e.x2, e.y2)
+ let b1 = find_closest_node(b_list, e.x1, e.y1)
+ let b2 = find_closest_node(b_list, e.x2, e.y2)
+ let a = a1 >= 0 ? a1 : a2
+ let b = b1 >= 0 ? b1 : b2
+ if (a < 0 || b < 0)
+ console.log("CANNOT FIND EDGE", e, a_list[a], b_list[b])
+ if (!a_list[a][prop_name])
+ a_list[a][prop_name] = []
+ set_add(a_list[a][prop_name], b)
+ }
+}
+
+/* WASHINGTON'S WAR */
+
+function sort_alpha(list) {
+ list.sort((a,b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)
+}
+
+sort_alpha(points.fortress)
+sort_alpha(points.winter_quarters)
+sort_alpha(points.space)
+points.colony.reverse()
+
+const data = {}
+
+data.spaces = [ ...points.fortress, ...points.winter_quarters, ...points.space ]
+data.colonies = [ ...points.colony ]
+data.seas = [ ...points.sea ]
+
+connect_edge_2way(data.spaces, "path")
+connect_edge_2way(data.spaces, "wilderness")
+connect_edge_1way(data.colonies, data.spaces, "colony", "spaces")
+connect_edge_1way(data.seas, data.spaces, "sea", "spaces")
+
+console.log(JSON.stringify(data,0,4))
+
+/*
+function find_closest_node(list, x, y) {
+ let nd = Infinity, nn = null
+
+ for (let n of list) {
+ let d = Math.hypot(n.x - x, n.y - y)
+ if (d < nd) {
+ nd = d
+ nn = n
+ }
+ }
+
+ if (!nn) {
+ console.log("NOT FOUND", x, y)
+ return [ null, 0 ]
+ }
+
+ return [ nn, nd ]
+}
+
+function find_enclosing_rect(list, x, y) {
+ for (let [x1, y1, x2, y2] of list) {
+ if (x >= x1 && x <= x2)
+ if (y >= y1 && y <= y2)
+ return true
+ }
+ return false
+}
+
+
+function make_spaces(points) {
+ let spaces = []
+ for (let [x,y] of points) {
+ let [ name, dist ] = find_closest_node(labels, x, y)
+ if (dist > 50) console.log("DISTANCE TOO FAR", x, y, dist)
+
+ spaces.push({ name: name.name, x, y })
+ }
+ return spaces
+}
+
+let data = {}
+
+data.spaces = make_spaces([ ...points.fortress, ...points.winter_quarters, ...points.space ])
+
+console.log(data)
+
+function find_closest_point(x, y) {
+ let nd = Infinity, nn = -1
+
+ for (let i = 0; i < points.length; ++i) {
+ let n = points[i]
+ let d = Math.hypot(n.x - x, n.y - y)
+ if (d < nd) {
+ nd = d
+ nn = i
+ }
+ }
+
+ return nn
+}
+
+// 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 > 15) {
+ console.log("DISTANCE TOO FAR", key,x,y, "dist=" + dist, "name=" + node.name)
+ }
+ 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 country = "UNKNOWN"
+ if (find_enclosing_rect(rects.$Empire, x, y)) {
+ country = EMPIRE
+ }
+ else if (find_enclosing_rect(rects.$Austria, x, y)) {
+ country = AUSTRIA
+ }
+ else if (find_enclosing_rect(rects.$Hanover, x, y)) {
+ country = HANOVER
+ }
+ else if (find_enclosing_rect(rects.$Saxony, x, y)) {
+ country = SAXONY
+ }
+ else if (find_enclosing_rect(rects.$Sweden, x, y)) {
+ country = SWEDEN
+ }
+ else if (find_enclosing_rect(rects.$Poland, x, y)) {
+ country = POLAND
+ }
+ else if (find_enclosing_rect(rects.$Prussia, x, y)) {
+ country = PRUSSIA
+ }
+
+ if (country === "UNKNOWN")
+ console.log("no country:", node)
+
+ cities.push({
+ name: node.name,
+ country,
+ suit,
+ type: key,
+ x: Math.round(x),
+ y: Math.round(y),
+ adjacent: [],
+ major_roads: [],
+ roads: [],
+ })
+ } else {
+ let [ dupname, dupdist ] = find_closest_node(all_labels, x, y)
+ console.log("ALREADY USED", dupname, dupdist, x, y)
+ }
+ }
+}
+
+for (let e of edges.major_road) {
+ let a = find_closest_point(e.x1, e.y1)
+ let b = find_closest_point(e.x2, e.y2)
+ set_add(cities[a].major_roads, b)
+ set_add(cities[b].major_roads, a)
+ set_add(cities[a].adjacent, b)
+ set_add(cities[b].adjacent, a)
+}
+
+for (let e of edges.road) {
+ let a = find_closest_point(e.x1, e.y1)
+ let b = find_closest_point(e.x2, e.y2)
+ set_add(cities[a].roads, b)
+ set_add(cities[b].roads, a)
+ set_add(cities[a].adjacent, b)
+ set_add(cities[b].adjacent, a)
+}
+
+console.log("if (typeof module === 'object') module.exports = data")
+*/