diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/gendata.js | 488 | ||||
-rw-r--r-- | tools/layout.json | 3728 | ||||
-rw-r--r-- | tools/layout.svg | 343 | ||||
-rw-r--r-- | tools/parse-layout-old.js | 466 | ||||
-rw-r--r-- | tools/parse-layout.js | 325 | ||||
-rw-r--r-- | tools/process-layout.js | 164 | ||||
-rw-r--r-- | tools/rotate_year.sh | 8 |
7 files changed, 5078 insertions, 444 deletions
diff --git a/tools/gendata.js b/tools/gendata.js new file mode 100644 index 0000000..72379ec --- /dev/null +++ b/tools/gendata.js @@ -0,0 +1,488 @@ +"use strict" + +const fs = require("fs") + +let data = JSON.parse(fs.readFileSync("tools/data.json", "utf-8")) + +function make_index_from_list(list) { + let map = {} + for (let i = 0; i < list.length; ++i) + map[list[i]] = i + return map +} + +/* GENERALS */ + +data.generals = [ + { name: "Arnold", owner: "American", strategy: 1, battle: 3, agility: 2, bonus: false }, + { name: "Gates", owner: "American", strategy: 2, battle: 2, agility: 1, bonus: false }, + { name: "Greene", owner: "American", strategy: 1, battle: 4, agility: 2, bonus: true }, + { name: "Lafayette", owner: "American", strategy: 1, battle: 2, agility: 1, bonus: false }, + { name: "Lee", owner: "American", strategy: 2, battle: 1, agility: 1, bonus: false }, + { name: "Lincoln", owner: "American", strategy: 2, battle: 1, agility: 1, bonus: false }, + { name: "Washington", owner: "American", strategy: 1, battle: 5, agility: 2, bonus: true }, + + { name: "Rochambeau", owner: "French", strategy: 2, battle: 4, agility: 2, bonus: false }, + + { name: "Burgoyne", owner: "British", strategy: 2, battle: 2, agility: 1, bonus: false }, + { name: "Carleton", owner: "British", strategy: 3, battle: 3, agility: 2, bonus: false }, + { name: "Clinton", owner: "British", strategy: 3, battle: 4, agility: 2, bonus: false }, + { name: "Cornwallis", owner: "British", strategy: 2, battle: 4, agility: 2, bonus: false }, + { name: "Howe", owner: "British", strategy: 3, battle: 6, agility: 3, bonus: false }, +] + +data.general_index = make_index_from_list(data.generals.map(x=>x.name)) + +/* COLONIES */ + +data.colony_name = [ "Canada", "NH", "NY", "MA", "CT", "RI", "PA", "NJ", "MD", "DE", "VA", "NC", "SC", "GA" ] + +const Canada = 0 +const NH = 1 +const NY = 2 +const MA = 3 +const CT = 4 +const RI = 5 +const PA = 6 +const NJ = 7 +const MD = 8 +const DE = 9 +const VA = 10 +const NC = 11 +const SC = 12 +const GA = 13 + +/* CARDS */ + +const CARD_3_OPS = { title: "3 OPS", type: "ops", count: 3 } +const CARD_2_OPS = { title: "2 OPS", type: "ops", count: 2 } +const CARD_1_OPS = { title: "1 OPS", type: "ops", count: 1 } + +data.cards = [ + null, + + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + CARD_3_OPS, + + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + CARD_2_OPS, + + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + CARD_1_OPS, + + /* 67 */ + { + title: "Minor Campaign", + type: "campaign", + count: 2, + }, + + /* 68 */ + { + title: "Minor Campaign", + type: "campaign", + count: 2, + }, + + /* 69 */ + { + title: "Minor Campaign", + type: "campaign", + count: 2, + }, + + /* 70 */ + { + title: "Major Campaign", + type: "campaign", + count: 3, + }, + + /* 71 */ + { + full_title: "North's Government Falls - The War Ends in 1779", + title: "The War Ends in 1779", + type: "mandatory-event", + event: "the_war_ends", + year: 1779, + }, + + /* 72 */ + { + full_title: "North's Government Falls - The War Ends in 1780", + title: "The War Ends in 1780", + type: "mandatory-event", + event: "the_war_ends", + year: 1780, + }, + + /* 73 */ + { + full_title: "North's Government Falls - The War Ends in 1781", + title: "The War Ends in 1781", + type: "mandatory-event", + event: "the_war_ends", + year: 1781, + }, + + /* 74 */ + { + full_title: "North's Government Falls - The War Ends in 1782", + title: "The War Ends in 1782", + type: "mandatory-event", + event: "the_war_ends", + year: 1782, + }, + + /* 75 */ + { + full_title: "North's Government Falls - The War Ends in 1783", + title: "The War Ends in 1783", + type: "mandatory-event", + event: "the_war_ends", + year: 1783, + }, + + /* 76 */ + { + title: "Henry Know Continental Artillery Commander", + type: "american-battle", + }, + + /* 77 */ + { + title: "Jane McCrea Indian Atrocity Sparks Outrage", + type: "american-event", + event: "place_american_pc", + count: 2, + once: true, + }, + + /* 78 */ + { + title: "Iroquois Uprising!", + type: "british-event", + event: "remove_american_pc_from_non_port", + where: [ NH, NY, PA ], + count: 2, + }, + + /* 79 */ + { + title: "Joseph Brant Leads an Iroquois Raid", + type: "british-event", + event: "remove_american_pc_from_non_port", + where: [ NH, NY, PA ], + count: 2, + }, + + /* 80 */ + { + title: "Lt. Colonel Simcoe's Queen's Rangers", + type: "british-event", + event: "remove_american_pc_within_two_spaces_of_a_british_general", + count: 2, + }, + + /* 81 */ + { + title: "D'Estaing Sails for the Caribbean", + type: "british-event", + when: "after_french_alliance", + event: "remove_french_navy", + }, + + /* 82 */ + { + title: "Banastre Tarleton's Waxhaws Massacre", + type: "british-event-or-battle", + event: "remove_american_cu", + }, + + /* 83 */ + { + title: "Lord George Germaine Offers Royal Amnesty", + type: "british-event", + event: "remove_american_pc", + count: 2, + }, + + /* 84 */ + { + title: "George Rogers Clark Leads a Western Offensive", + type: "american-event", + event: "remove_random_british_card", + }, + + /* 85 */ + { + title: "Don Bernardo Galvez Captures Pensacola", + type: "american-event", + when: "european_war_in_effect", + event: "remove_british_cu", + count: 2, + }, + + /* 86 */ + { + title: "Baron von Steuben Trains the Continental Army", + type: "american-event", + event: "baron_von_steuben_trains_the_continental_army", + }, + + /* 87 */ + { + title: "Lord North Offers a Royal Amnesty", + type: "british-event", + event: "remove_american_pc", + count: 4, + once: true, + }, + + /* 88 */ + { + title: "The Swamp Fox, Francis Marion", + type: "american-event", + event: "remove_british_pc_from", + where: [ NC, SC, GA ], + count: 2, + }, + + /* 89 */ + { + title: "The Gamecock: Thomas Sumter", + type: "american-event", + event: "remove_british_pc_from", + where: [ NC, SC, GA ], + count: 2, + }, + + /* 90 */ + { + title: "Josiah Martin Rallies North Carolina Loyalists", + type: "british-event", + event: "remove_american_pc_from", + where: [ NC ], + count: 2, + }, + + /* 91 */ + { + title: 'Thomas Paine Publishes Pamphlets "Common Sense" and "The American Crisis"', + type: "american-event", + event: "place_american_pc_in", + where: [ NH, NY, MA, CT, RI, PA, NJ, MD, DE, VA, NC, SC, GA ], + count: 3, + once: true, + }, + + /* 92 */ + { + title: "Nathan Hale, American Martyr", + type: "american-event", + event: "place_american_pc", + count: 2, + once: true, + }, + + /* 93 */ + { + title: "John Glover's Marblehead Regiment", + type: "american-event", + event: "john_glovers_marblehead_regiment", + }, + + /* 94 */ + { + title: "Pennsylvania and New Jersey Line Mutinies", + type: "british-event", + event: "pennsylvania_and_new_jersey_line_mutinies", + }, + + /* 95 */ + { + title: "William Pitt Urges Peace Talks", + type: "british-event", + when: "before_french_alliance", + event: "remove_american_pc", + count: 2, + reshuffle: "if_played", + }, + + /* 96 */ + { + title: "Hortelez et Cie: Clandestine French and Spanish Aid", + type: "american-event", + when: "before_french_alliance", + event: "advance_french_alliance", + reshuffle: "if_discarded", + count: 2, + }, + + /* 97 */ + { + title: "Admiral Suffren Wins a Naval Victory", + type: "american-event", + when: "after_french_alliance", + event: "remove_random_british_card", + }, + + /* 98 */ + { + title: '"Mad" Anthony Wayne', + type: "american-battle", + }, + + /* 99 */ + { + title: "Declaration of Independence", + type: "mandatory-event", + event: "declaration_of_independence", + once: true, + reshuffle: "if_played", + tournament: true, + }, + + /* 100 */ + { + title: "Benedict Arnold's Treason Undermines the Patriot Cause", + type: "british-battle", + event: "remove_benedict_arnold", + once: true, + }, + + /* 101 */ + { + title: "Benjamin Franklin: Minister to France", + type: "mandatory-event", + event: "advance_french_alliance", + count: 4, + once: true, + tournament: true, + }, + + /* 102 */ + { + title: "Admiral Rodney Captures St. Eustatius", + type: "british-event", + event: "remove_random_american_card", + when: "european_war_in_effect", + once: true, + }, + + /* 103 */ + { + title: "Thaddeus Kosciuszco Constructs Engineering Works", + type: "american-battle", + }, + + /* 104 */ + { + title: "Light Horse Harry Lee", + type: "american-battle", + }, + + /* 105 */ + { + title: "Morgan's Riflemen", + type: "american-battle", + }, + + /* 106 */ + { + title: "John Paul Jones' Shipping Raids", + type: "american-event", + event: "remove_random_british_card", + }, + + /* 107 */ + { + title: "British Light Infantry", + type: "british-battle", + }, + + /* 108 */ + { + title: "Lord Sandwich Coastal Raids", + type: "british-event", + event: "lord_sandwich_coastal_raids", + }, + + /* 109 */ + { + title: "Edward Bancroft, British Double Agent", + type: "british-event", + event: "remove_random_american_card", + }, + + /* 110 */ + { + title: "Hessian Infantry Bayonet Charge", + type: "british-battle", + }, +] + +/* OUTPUT */ + +console.log("const data = " + JSON.stringify(data,0,'\t')) +console.log("if (typeof module === 'object') module.exports = data") diff --git a/tools/layout.json b/tools/layout.json new file mode 100644 index 0000000..78b8e34 --- /dev/null +++ b/tools/layout.json @@ -0,0 +1,3728 @@ +{ + "boxes": { + "fortified_port": [ + { + "x": 450, + "y": 2052, + "w": 68, + "h": 68, + "name": "Charleston" + }, + { + "x": 852, + "y": 964, + "w": 68, + "h": 67, + "name": "Philadelphia" + }, + { + "x": 1006, + "y": 161, + "w": 68, + "h": 68, + "name": "Montreal" + }, + { + "x": 1129, + "y": 60, + "w": 67, + "h": 67, + "name": "Quebec" + } + ], + "winter_quarters": [ + { + "x": 995, + "y": 353, + "w": 79, + "h": 79, + "name": "Ticonderoga" + }, + { + "x": 1126, + "y": 339, + "w": 79, + "h": 79, + "name": "Norwich" + }, + { + "x": 878, + "y": 481, + "w": 79, + "h": 79, + "name": "Fort Stanwix" + }, + { + "x": 967, + "y": 624, + "w": 79, + "h": 79, + "name": "Albany" + }, + { + "x": 1097, + "y": 622, + "w": 79, + "h": 78, + "name": "Springfield" + }, + { + "x": 1328, + "y": 590, + "w": 79, + "h": 78, + "name": "Boston" + }, + { + "x": 1291, + "y": 733, + "w": 78, + "h": 79, + "name": "Newport" + }, + { + "x": 1185, + "y": 747, + "w": 78, + "h": 78, + "name": "Hartford" + }, + { + "x": 1025, + "y": 835, + "w": 79, + "h": 79, + "name": "New York" + }, + { + "x": 687, + "y": 745, + "w": 78, + "h": 78, + "name": "Wyoming Valley" + }, + { + "x": 441, + "y": 955, + "w": 78, + "h": 79, + "name": "Pittsburgh" + }, + { + "x": 887, + "y": 1077, + "w": 78, + "h": 79, + "name": "Wilmington DE" + }, + { + "x": 771, + "y": 1103, + "w": 79, + "h": 79, + "name": "Baltimore" + }, + { + "x": 654, + "y": 1215, + "w": 79, + "h": 78, + "name": "Alexandria" + }, + { + "x": 610, + "y": 1321, + "w": 78, + "h": 78, + "name": "Richmond" + }, + { + "x": 436, + "y": 1254, + "w": 78, + "h": 79, + "name": "Charlottesville" + }, + { + "x": 783, + "y": 1448, + "w": 78, + "h": 79, + "name": "Norfolk" + } + ], + "regular": [ + { + "x": 226.5, + "y": 2266.5, + "w": 81, + "h": 81, + "name": "Savannah" + }, + { + "x": 139.01387, + "y": 2055.9861, + "w": 81, + "h": 81, + "name": "Augusta" + }, + { + "x": 222.01385, + "y": 1927.5, + "w": 81, + "h": 81, + "name": "Ninety Six" + }, + { + "x": 403.05807, + "y": 1901.0138, + "w": 81, + "h": 81, + "name": "Eutaw Springs" + }, + { + "x": 573.5592, + "y": 1910.5598, + "w": 81, + "h": 81, + "name": "Georgetown" + }, + { + "x": 675.0592, + "y": 1811.8098, + "w": 81, + "h": 81, + "name": "Wilmington" + }, + { + "x": 495.05920000000003, + "y": 1790.0598, + "w": 81, + "h": 81, + "name": "Cheraw" + }, + { + "x": 345.3092, + "y": 1768.3098, + "w": 81, + "h": 81, + "name": "Camden" + }, + { + "x": 605.8092, + "y": 1666.5598, + "w": 81, + "h": 81, + "name": "Wake (Raleigh)" + }, + { + "x": 763.3092, + "y": 1665.5598, + "w": 81, + "h": 81, + "name": "New Bern" + }, + { + "x": 483.55920000000003, + "y": 1577.5598, + "w": 81, + "h": 81, + "name": "Hillsboro" + }, + { + "x": 308.3092, + "y": 1556.0598, + "w": 81, + "h": 81, + "name": "Salem" + }, + { + "x": 214.5592, + "y": 1648.5598, + "w": 81, + "h": 81, + "name": "Charlotte" + }, + { + "x": 122.3092, + "y": 1563.3098, + "w": 81, + "h": 81, + "name": "Gilbert Town" + }, + { + "x": 73.5592, + "y": 1768.8098, + "w": 81, + "h": 81, + "name": "Fort Prince George" + }, + { + "x": 60.260580000000004, + "y": 1446.7491, + "w": 81, + "h": 81, + "name": "Abingdon" + }, + { + "x": 211.40466, + "y": 1403.6156, + "w": 81, + "h": 81, + "name": "Fort Chiswell" + }, + { + "x": 348.58337, + "y": 1397.2516, + "w": 81, + "h": 81, + "name": "Fincastle" + }, + { + "x": 485.93884, + "y": 1439.1477, + "w": 81, + "h": 81, + "name": "Lynch's Ferry" + }, + { + "x": 634.07404, + "y": 1441.644, + "w": 81, + "h": 81, + "name": "Petersburg" + }, + { + "x": 766.12952, + "y": 1312.0383, + "w": 81, + "h": 81, + "name": "Yorktown" + }, + { + "x": 131.70384, + "y": 1213.4077, + "w": 81, + "h": 81, + "name": "Point Pleasant" + }, + { + "x": 146.95384, + "y": 979.7827, + "w": 81, + "h": 81, + "name": "Bassett Town" + }, + { + "x": 446.21503, + "y": 1093.475, + "w": 81, + "h": 81, + "name": "Fort Cumberland" + }, + { + "x": 645.7276, + "y": 1092.4473, + "w": 81, + "h": 81, + "name": "Frederick Town" + }, + { + "x": 588.75372, + "y": 987.3384000000001, + "w": 81, + "h": 81, + "name": "York" + }, + { + "x": 683.25372, + "y": 895.58838, + "w": 81, + "h": 81, + "name": "Reading" + }, + { + "x": 554.00372, + "y": 875.33838, + "w": 81, + "h": 81, + "name": "Harrisburg" + }, + { + "x": 863.60297, + "y": 826.91376, + "w": 81, + "h": 81, + "name": "Morristown" + }, + { + "x": 960.8301, + "y": 937.04565, + "w": 81, + "h": 81, + "name": "New Brunswick" + }, + { + "x": 996.8300999999999, + "y": 1069.7957, + "w": 81, + "h": 81, + "name": "Monmouth" + }, + { + "x": 1145.8301, + "y": 863.54565, + "w": 81, + "h": 81, + "name": "Long Island" + }, + { + "x": 1087.5801, + "y": 731.54565, + "w": 81, + "h": 81, + "name": "New Haven" + }, + { + "x": 954.33008, + "y": 742.29565, + "w": 81, + "h": 81, + "name": "Westchester" + }, + { + "x": 1217.8301, + "y": 623.54565, + "w": 81, + "h": 81, + "name": "Lexington Concord" + }, + { + "x": 1393.8301, + "y": 700.54565, + "w": 81, + "h": 81, + "name": "Barnstable" + }, + { + "x": 1333.5618, + "y": 405.97501, + "w": 81, + "h": 81, + "name": "Falmouth" + }, + { + "x": 1213.5618, + "y": 456.47501, + "w": 81, + "h": 81, + "name": "Concord" + }, + { + "x": 1100.8118, + "y": 481.97504000000004, + "w": 81, + "h": 81, + "name": "Brattleboro" + }, + { + "x": 991.3118, + "y": 491.22504000000004, + "w": 81, + "h": 81, + "name": "Saratoga" + }, + { + "x": 767.56177, + "y": 419.47504, + "w": 81, + "h": 81, + "name": "Oswego" + }, + { + "x": 667.56177, + "y": 577.97504, + "w": 81, + "h": 81, + "name": "Genesee" + }, + { + "x": 461.06177, + "y": 521.47504, + "w": 81, + "h": 81, + "name": "Fort Niagara" + }, + { + "x": 54.828918, + "y": 667.84613, + "w": 81, + "h": 81, + "name": "Fort Detroit" + }, + { + "x": 179.39716, + "y": 2389.0383, + "w": 81, + "h": 81, + "name": "St. Mary's" + } + ], + "sea": [ + { + "x": 351, + "y": 2352, + "w": 97, + "h": 83, + "name": "Sea7" + }, + { + "x": 629, + "y": 2022, + "w": 97, + "h": 83, + "name": "Sea6" + }, + { + "x": 938, + "y": 1389, + "w": 97, + "h": 83, + "name": "Sea5" + }, + { + "x": 1049, + "y": 1169, + "w": 97, + "h": 83, + "name": "Sea4" + }, + { + "x": 1205, + "y": 975, + "w": 97, + "h": 83, + "name": "Sea3" + }, + { + "x": 1461, + "y": 508, + "w": 97, + "h": 84, + "name": "Sea2" + }, + { + "x": 1268, + "y": 60, + "w": 97, + "h": 83, + "name": "Sea1" + } + ], + "colony": [ + { + "x": 1171, + "y": 1558, + "w": 66, + "h": 57, + "name": "GA" + }, + { + "x": 1218, + "y": 1486, + "w": 67, + "h": 58, + "name": "SC" + }, + { + "x": 1267, + "y": 1415, + "w": 66, + "h": 57, + "name": "NC" + }, + { + "x": 1248, + "y": 1344, + "w": 67, + "h": 58, + "name": "VA" + }, + { + "x": 1306, + "y": 1274, + "w": 66, + "h": 57, + "name": "MD" + }, + { + "x": 1383, + "y": 1274, + "w": 66, + "h": 57, + "name": "DE" + }, + { + "x": 1306, + "y": 1201, + "w": 66, + "h": 58, + "name": "PA" + }, + { + "x": 1383, + "y": 1196, + "w": 66, + "h": 58, + "name": "NJ" + }, + { + "x": 1462, + "y": 1163, + "w": 66, + "h": 58, + "name": "CT" + }, + { + "x": 1540, + "y": 1163, + "w": 66, + "h": 58, + "name": "RI" + }, + { + "x": 1498, + "y": 1088, + "w": 67, + "h": 58, + "name": "MA" + }, + { + "x": 1382, + "y": 1089, + "w": 66, + "h": 58, + "name": "NY" + }, + { + "x": 1465, + "y": 1014, + "w": 66, + "h": 58, + "name": "NH" + }, + { + "x": 1383, + "y": 975, + "w": 66, + "h": 57, + "name": "Canada" + } + ], + "box": [ + { + "x": 1358, + "y": 1673, + "w": 214, + "h": 206, + "name": "British Reinforcement Box" + }, + { + "x": 294, + "y": 258, + "w": 214, + "h": 206, + "name": "American Leader Reinforcements" + }, + { + "x": 63, + "y": 258, + "w": 214, + "h": 207, + "name": "French Reinforcements" + }, + { + "x": 542, + "y": 332, + "w": 88, + "h": 104, + "name": "Continental Congress Dispersed" + }, + { + "x": 1400, + "y": 46, + "w": 205, + "h": 136, + "name": "Captured Generals" + } + ], + "Card Boxes": [ + { + "x": 904, + "y": 1915, + "w": 199, + "h": 277, + "name": "BRC" + }, + { + "x": 1137, + "y": 1915, + "w": 199, + "h": 277, + "name": "ARC1" + }, + { + "x": 1370, + "y": 1915, + "w": 199.00003, + "h": 277, + "name": "ARC2" + }, + { + "x": 1027, + "y": 1679, + "w": 278, + "h": 198.99998, + "name": "War Ends Card" + } + ], + "Game Turn": [ + { + "x": 904, + "y": 2368, + "w": 64, + "h": 72, + "name": "1775" + }, + { + "x": 970, + "y": 2368, + "w": 64, + "h": 72, + "name": "1776" + }, + { + "x": 1036, + "y": 2368, + "w": 64, + "h": 72, + "name": "1777" + }, + { + "x": 1102, + "y": 2368, + "w": 64, + "h": 72, + "name": "1778" + }, + { + "x": 1168, + "y": 2368, + "w": 65, + "h": 72, + "name": "1779" + }, + { + "x": 1235, + "y": 2368, + "w": 64, + "h": 72, + "name": "1780" + }, + { + "x": 1301, + "y": 2368, + "w": 64, + "h": 72, + "name": "1781" + }, + { + "x": 1367, + "y": 2368, + "w": 64, + "h": 72, + "name": "1782" + }, + { + "x": 1433, + "y": 2368, + "w": 64, + "h": 72, + "name": "1783" + } + ], + "French Alliance Track": [ + { + "x": 905, + "y": 2241, + "w": 64, + "h": 71, + "name": "0" + }, + { + "x": 971, + "y": 2241, + "w": 64, + "h": 71, + "name": "1" + }, + { + "x": 1037, + "y": 2241, + "w": 64, + "h": 71, + "name": "2" + }, + { + "x": 1103, + "y": 2241, + "w": 64, + "h": 71, + "name": "3" + }, + { + "x": 1169, + "y": 2241, + "w": 65, + "h": 71, + "name": "4" + }, + { + "x": 1236, + "y": 2241, + "w": 64, + "h": 71, + "name": "5" + }, + { + "x": 1302, + "y": 2241, + "w": 64, + "h": 71, + "name": "6" + }, + { + "x": 1368, + "y": 2241, + "w": 64, + "h": 71, + "name": "7" + }, + { + "x": 1434, + "y": 2241, + "w": 65, + "h": 71, + "name": "8" + }, + { + "x": 1501, + "y": 2241, + "w": 63, + "h": 71, + "name": "9" + } + ] + }, + "points": { + "fortified_port": [ + { + "x": 484, + "y": 2086, + "name": "Charleston" + }, + { + "x": 886, + "y": 997.5, + "name": "Philadelphia" + }, + { + "x": 1040, + "y": 195, + "name": "Montreal" + }, + { + "x": 1162.5, + "y": 93.5, + "name": "Quebec" + } + ], + "winter_quarters": [ + { + "x": 1034.5, + "y": 392.5, + "name": "Ticonderoga" + }, + { + "x": 1165.5, + "y": 378.5, + "name": "Norwich" + }, + { + "x": 917.5, + "y": 520.5, + "name": "Fort Stanwix" + }, + { + "x": 1006.5, + "y": 663.5, + "name": "Albany" + }, + { + "x": 1136.5, + "y": 661, + "name": "Springfield" + }, + { + "x": 1367.5, + "y": 629, + "name": "Boston" + }, + { + "x": 1330, + "y": 772.5, + "name": "Newport" + }, + { + "x": 1224, + "y": 786, + "name": "Hartford" + }, + { + "x": 1064.5, + "y": 874.5, + "name": "New York" + }, + { + "x": 726, + "y": 784, + "name": "Wyoming Valley" + }, + { + "x": 480, + "y": 994.5, + "name": "Pittsburgh" + }, + { + "x": 926, + "y": 1116.5, + "name": "Wilmington DE" + }, + { + "x": 810.5, + "y": 1142.5, + "name": "Baltimore" + }, + { + "x": 693.5, + "y": 1254, + "name": "Alexandria" + }, + { + "x": 649, + "y": 1360, + "name": "Richmond" + }, + { + "x": 475, + "y": 1293.5, + "name": "Charlottesville" + }, + { + "x": 822, + "y": 1487.5, + "name": "Norfolk" + } + ], + "regular": [ + { + "x": 267, + "y": 2307, + "name": "Savannah" + }, + { + "x": 179.51387, + "y": 2096.4861, + "name": "Augusta" + }, + { + "x": 262.51385, + "y": 1968, + "name": "Ninety Six" + }, + { + "x": 443.55807, + "y": 1941.5138, + "name": "Eutaw Springs" + }, + { + "x": 614.0592, + "y": 1951.0598, + "name": "Georgetown" + }, + { + "x": 715.5592, + "y": 1852.3098, + "name": "Wilmington" + }, + { + "x": 535.5592, + "y": 1830.5598, + "name": "Cheraw" + }, + { + "x": 385.8092, + "y": 1808.8098, + "name": "Camden" + }, + { + "x": 646.3092, + "y": 1707.0598, + "name": "Wake (Raleigh)" + }, + { + "x": 803.8092, + "y": 1706.0598, + "name": "New Bern" + }, + { + "x": 524.0592, + "y": 1618.0598, + "name": "Hillsboro" + }, + { + "x": 348.8092, + "y": 1596.5598, + "name": "Salem" + }, + { + "x": 255.0592, + "y": 1689.0598, + "name": "Charlotte" + }, + { + "x": 162.8092, + "y": 1603.8098, + "name": "Gilbert Town" + }, + { + "x": 114.0592, + "y": 1809.3098, + "name": "Fort Prince George" + }, + { + "x": 100.76058, + "y": 1487.2491, + "name": "Abingdon" + }, + { + "x": 251.90466, + "y": 1444.1156, + "name": "Fort Chiswell" + }, + { + "x": 389.08337, + "y": 1437.7516, + "name": "Fincastle" + }, + { + "x": 526.43884, + "y": 1479.6477, + "name": "Lynch's Ferry" + }, + { + "x": 674.57404, + "y": 1482.144, + "name": "Petersburg" + }, + { + "x": 806.62952, + "y": 1352.5383, + "name": "Yorktown" + }, + { + "x": 172.20384, + "y": 1253.9077, + "name": "Point Pleasant" + }, + { + "x": 187.45384, + "y": 1020.2827, + "name": "Bassett Town" + }, + { + "x": 486.71503, + "y": 1133.975, + "name": "Fort Cumberland" + }, + { + "x": 686.2276, + "y": 1132.9473, + "name": "Frederick Town" + }, + { + "x": 629.25372, + "y": 1027.8384, + "name": "York" + }, + { + "x": 723.75372, + "y": 936.08838, + "name": "Reading" + }, + { + "x": 594.50372, + "y": 915.83838, + "name": "Harrisburg" + }, + { + "x": 904.10297, + "y": 867.41376, + "name": "Morristown" + }, + { + "x": 1001.3301, + "y": 977.54565, + "name": "New Brunswick" + }, + { + "x": 1037.3301, + "y": 1110.2957, + "name": "Monmouth" + }, + { + "x": 1186.3301, + "y": 904.04565, + "name": "Long Island" + }, + { + "x": 1128.0801, + "y": 772.04565, + "name": "New Haven" + }, + { + "x": 994.83008, + "y": 782.79565, + "name": "Westchester" + }, + { + "x": 1258.3301, + "y": 664.04565, + "name": "Lexington Concord" + }, + { + "x": 1434.3301, + "y": 741.04565, + "name": "Barnstable" + }, + { + "x": 1374.0618, + "y": 446.47501, + "name": "Falmouth" + }, + { + "x": 1254.0618, + "y": 496.97501, + "name": "Concord" + }, + { + "x": 1141.3118, + "y": 522.47504, + "name": "Brattleboro" + }, + { + "x": 1031.8118, + "y": 531.72504, + "name": "Saratoga" + }, + { + "x": 808.06177, + "y": 459.97504, + "name": "Oswego" + }, + { + "x": 708.06177, + "y": 618.47504, + "name": "Genesee" + }, + { + "x": 501.56177, + "y": 561.97504, + "name": "Fort Niagara" + }, + { + "x": 95.328918, + "y": 708.34613, + "name": "Fort Detroit" + }, + { + "x": 219.89716, + "y": 2429.5383, + "name": "St. Mary's" + } + ], + "sea": [ + { + "x": 399.5, + "y": 2393.5, + "name": "Sea7" + }, + { + "x": 677.5, + "y": 2063.5, + "name": "Sea6" + }, + { + "x": 986.5, + "y": 1430.5, + "name": "Sea5" + }, + { + "x": 1097.5, + "y": 1210.5, + "name": "Sea4" + }, + { + "x": 1253.5, + "y": 1016.5, + "name": "Sea3" + }, + { + "x": 1509.5, + "y": 550, + "name": "Sea2" + }, + { + "x": 1316.5, + "y": 101.5, + "name": "Sea1" + } + ], + "colony": [ + { + "x": 1204, + "y": 1586.5, + "name": "GA" + }, + { + "x": 1251.5, + "y": 1515, + "name": "SC" + }, + { + "x": 1300, + "y": 1443.5, + "name": "NC" + }, + { + "x": 1281.5, + "y": 1373, + "name": "VA" + }, + { + "x": 1339, + "y": 1302.5, + "name": "MD" + }, + { + "x": 1416, + "y": 1302.5, + "name": "DE" + }, + { + "x": 1339, + "y": 1230, + "name": "PA" + }, + { + "x": 1416, + "y": 1225, + "name": "NJ" + }, + { + "x": 1495, + "y": 1192, + "name": "CT" + }, + { + "x": 1573, + "y": 1192, + "name": "RI" + }, + { + "x": 1531.5, + "y": 1117, + "name": "MA" + }, + { + "x": 1415, + "y": 1118, + "name": "NY" + }, + { + "x": 1498, + "y": 1043, + "name": "NH" + }, + { + "x": 1416, + "y": 1003.5, + "name": "Canada" + } + ], + "box": [ + { + "x": 1465, + "y": 1776, + "name": "British Reinforcement Box" + }, + { + "x": 401, + "y": 361, + "name": "American Leader Reinforcements" + }, + { + "x": 170, + "y": 361.5, + "name": "French Reinforcements" + }, + { + "x": 586, + "y": 384, + "name": "Continental Congress Dispersed" + }, + { + "x": 1502.5, + "y": 114, + "name": "Captured Generals" + } + ], + "Card Boxes": [ + { + "x": 1003.5, + "y": 2053.5, + "name": "BRC" + }, + { + "x": 1236.5, + "y": 2053.5, + "name": "ARC1" + }, + { + "x": 1469.500015, + "y": 2053.5, + "name": "ARC2" + }, + { + "x": 1166, + "y": 1778.49999, + "name": "War Ends Card" + } + ], + "Game Turn": [ + { + "x": 936, + "y": 2404, + "name": "1775" + }, + { + "x": 1002, + "y": 2404, + "name": "1776" + }, + { + "x": 1068, + "y": 2404, + "name": "1777" + }, + { + "x": 1134, + "y": 2404, + "name": "1778" + }, + { + "x": 1200.5, + "y": 2404, + "name": "1779" + }, + { + "x": 1267, + "y": 2404, + "name": "1780" + }, + { + "x": 1333, + "y": 2404, + "name": "1781" + }, + { + "x": 1399, + "y": 2404, + "name": "1782" + }, + { + "x": 1465, + "y": 2404, + "name": "1783" + } + ], + "French Alliance Track": [ + { + "x": 937, + "y": 2276.5, + "name": "0" + }, + { + "x": 1003, + "y": 2276.5, + "name": "1" + }, + { + "x": 1069, + "y": 2276.5, + "name": "2" + }, + { + "x": 1135, + "y": 2276.5, + "name": "3" + }, + { + "x": 1201.5, + "y": 2276.5, + "name": "4" + }, + { + "x": 1268, + "y": 2276.5, + "name": "5" + }, + { + "x": 1334, + "y": 2276.5, + "name": "6" + }, + { + "x": 1400, + "y": 2276.5, + "name": "7" + }, + { + "x": 1466.5, + "y": 2276.5, + "name": "8" + }, + { + "x": 1532.5, + "y": 2276.5, + "name": "9" + } + ] + }, + "edges": { + "path": [ + { + "x1": 227.01265, + "y1": 2390.0517, + "x2": 242.96720000000002, + "y2": 2339.5508, + "name": null, + "name1": "St. Mary's", + "name2": "Savannah" + }, + { + "x1": 199.02401, + "y1": 2132.0174, + "x2": 254.46493, + "y2": 2269.0997, + "name": null, + "name1": "Augusta", + "name2": "Savannah" + }, + { + "x1": 276.94694, + "y1": 2268.2133, + "x2": 450.40404, + "y2": 2099.316, + "name": null, + "name1": "Savannah", + "name2": "Charleston" + }, + { + "x1": 201.99439, + "y1": 2062.6086, + "x2": 241.40983, + "y2": 2001.6522, + "name": null, + "name1": "Augusta", + "name2": "Ninety Six" + }, + { + "x1": 145.20426, + "y1": 1830.9903, + "x2": 237.45150999999998, + "y2": 1937.1538, + "name": null, + "name1": "Fort Prince George", + "name2": "Ninety Six" + }, + { + "x1": 284.32538, + "y1": 1934.4039, + "x2": 357.40648999999996, + "y2": 1837.6152, + "name": null, + "name1": "Ninety Six", + "name2": "Camden" + }, + { + "x1": 404.96645, + "y1": 1843.7387, + "x2": 429.42317, + "y2": 1904.1378000000002, + "name": null, + "name1": "Camden", + "name2": "Eutaw Springs" + }, + { + "x1": 460.98711, + "y1": 1978.2779, + "x2": 477.36157999999995, + "y2": 2045.6090000000002, + "name": null, + "name1": "Eutaw Springs", + "name2": "Charleston" + }, + { + "x1": 496.23604, + "y1": 2051.5256, + "x2": 576.1504, + "y2": 1963.1115, + "name": null, + "name1": "Charleston", + "name2": "Georgetown" + }, + { + "x1": 646.98186, + "y1": 1928.7791, + "x2": 689.27224, + "y2": 1883.0305, + "name": null, + "name1": "Georgetown", + "name2": "Wilmington" + }, + { + "x1": 556.73449, + "y1": 1865.4894, + "x2": 590.69173, + "y2": 1919.571, + "name": null, + "name1": "Cheraw", + "name2": "Georgetown" + }, + { + "x1": 575.69233, + "y1": 1829.9903, + "x2": 676.98091, + "y2": 1842.365, + "name": null, + "name1": "Cheraw", + "name2": "Wilmington" + }, + { + "x1": 425.11313, + "y1": 1812.7409, + "x2": 497.1111, + "y2": 1822.0322, + "name": null, + "name1": "Camden", + "name2": "Cheraw" + }, + { + "x1": 286.90869, + "y1": 1713.7435, + "x2": 358.4066, + "y2": 1780.7, + "name": null, + "name1": "Charlotte", + "name2": "Camden" + }, + { + "x1": 149.36454, + "y1": 1641.7822, + "x2": 120.95485000000001, + "y2": 1769.7419, + "name": null, + "name1": "Gilbert Town", + "name2": "Fort Prince George" + }, + { + "x1": 91.330808, + "y1": 1526.2489, + "x2": 98.12225600000001, + "y2": 1772.4086, + "name": null, + "name1": "Abingdon", + "name2": "Fort Prince George" + }, + { + "x1": 193.54031, + "y1": 1630.0024, + "x2": 227.19063, + "y2": 1659.8424, + "name": null, + "name1": "Gilbert Town", + "name2": "Charlotte" + }, + { + "x1": 278.7005, + "y1": 1656.8285, + "x2": 316.11605, + "y2": 1620.4962, + "name": null, + "name1": "Charlotte", + "name2": "Salem" + }, + { + "x1": 385.32252, + "y1": 1600.0801, + "x2": 488.73627999999997, + "y2": 1612.1214, + "name": null, + "name1": "Salem", + "name2": "Hillsboro" + }, + { + "x1": 370.08352, + "y1": 1630.7156, + "x2": 509.69412, + "y2": 1800.5745, + "name": null, + "name1": "Salem", + "name2": "Cheraw" + }, + { + "x1": 669.35138, + "y1": 1740.1481, + "x2": 704.3551299999999, + "y2": 1813.8239, + "name": null, + "name1": "Wake (Raleigh)", + "name2": "Wilmington" + }, + { + "x1": 560.0883, + "y1": 1635.6726, + "x2": 619.77668, + "y2": 1677.2911000000001, + "name": null, + "name1": "Hillsboro", + "name2": "Wake (Raleigh)" + }, + { + "x1": 686.53009, + "y1": 1705.2652, + "x2": 763.91786, + "y2": 1704.3802, + "name": null, + "name1": "Wake (Raleigh)", + "name2": "New Bern" + }, + { + "x1": 672.10609, + "y1": 1522.7905, + "x2": 654.12084, + "y2": 1667.7282, + "name": null, + "name1": "Petersburg", + "name2": "Wake (Raleigh)" + }, + { + "x1": 555.65124, + "y1": 1592.7885, + "x2": 647.69018, + "y2": 1511.7075000000002, + "name": null, + "name1": "Hillsboro", + "name2": "Petersburg" + }, + { + "x1": 714.73008, + "y1": 1482.1667, + "x2": 782.7696100000001, + "y2": 1484.375, + "name": null, + "name1": "Petersburg", + "name2": "Norfolk" + }, + { + "x1": 822.35191, + "y1": 1526.7073, + "x2": 811.0189, + "y2": 1666.6615, + "name": null, + "name1": "Norfolk", + "name2": "New Bern" + }, + { + "x1": 382.48926, + "y1": 1573.8725, + "x2": 494.40279, + "y2": 1501.6245, + "name": null, + "name1": "Salem", + "name2": "Lynch's Ferry" + }, + { + "x1": 425.69638, + "y1": 1447.0844, + "x2": 489.44458999999995, + "y2": 1465.5004999999999, + "name": null, + "name1": "Fincastle", + "name2": "Lynch's Ferry" + }, + { + "x1": 551.06786, + "y1": 1449.2093, + "x2": 610.61031, + "y2": 1393.6397, + "name": null, + "name1": "Lynch's Ferry", + "name2": "Richmond" + }, + { + "x1": 662.68958, + "y1": 1398.8774, + "x2": 669.6478999999999, + "y2": 1442.3761000000002, + "name": null, + "name1": "Richmond", + "name2": "Petersburg" + }, + { + "x1": 564.95299, + "y1": 1489.0395, + "x2": 634.49253, + "y2": 1488.5332, + "name": null, + "name1": "Lynch's Ferry", + "name2": "Petersburg" + }, + { + "x1": 687.89742, + "y1": 1388.0028, + "x2": 783.35299, + "y2": 1463.584, + "name": null, + "name1": "Richmond", + "name2": "Norfolk" + }, + { + "x1": 687.6891, + "y1": 1357.2536, + "x2": 766.5200900000001, + "y2": 1354.1287, + "name": null, + "name1": "Richmond", + "name2": "Yorktown" + }, + { + "x1": 654.48163, + "y1": 1323.1295, + "x2": 670.77284, + "y2": 1290.5471, + "name": null, + "name1": "Richmond", + "name2": "Alexandria" + }, + { + "x1": 513.48556, + "y1": 1299.7969, + "x2": 610.02451, + "y2": 1338.5457000000001, + "name": null, + "name1": "Charlottesville", + "name2": "Richmond" + }, + { + "x1": 504.31918, + "y1": 1333.0042, + "x2": 534.06834, + "y2": 1442.8345000000002, + "name": null, + "name1": "Charlottesville", + "name2": "Lynch's Ferry" + }, + { + "x1": 403.38632, + "y1": 1400.343, + "x2": 442.32085, + "y2": 1332.546, + "name": null, + "name1": "Fincastle", + "name2": "Charlottesville" + }, + { + "x1": 186.99475, + "y1": 1293.3804, + "x2": 237.99332, + "y2": 1404.5856, + "name": null, + "name1": "Point Pleasant", + "name2": "Fort Chiswell" + }, + { + "x1": 136.12124, + "y1": 1468.0004, + "x2": 211.86909, + "y2": 1448.4593, + "name": null, + "name1": "Abingdon", + "name2": "Fort Chiswell" + }, + { + "x1": 288.28357, + "y1": 1440.7096, + "x2": 351.32347, + "y2": 1440.0012, + "name": null, + "name1": "Fort Chiswell", + "name2": "Fincastle" + }, + { + "x1": 137.20438, + "y1": 1503.9995, + "x2": 165.32871999999998, + "y2": 1564.081, + "name": null, + "name1": "Abingdon", + "name2": "Gilbert Town" + }, + { + "x1": 513.91845, + "y1": 1258.4465, + "x2": 651.77343, + "y2": 1152.0509, + "name": null, + "name1": "Charlottesville", + "name2": "Frederick Town" + }, + { + "x1": 697.18887, + "y1": 1171.3421, + "x2": 699.64694, + "y2": 1214.8824, + "name": null, + "name1": "Frederick Town", + "name2": "Alexandria" + }, + { + "x1": 732.5, + "y1": 1218.25, + "x2": 773, + "y2": 1180.25, + "name": null, + "name1": "Alexandria", + "name2": "Baltimore" + }, + { + "x1": 726.27128, + "y1": 1134.3849, + "x2": 772.0616600000001, + "y2": 1136.1348, + "name": null, + "name1": "Frederick Town", + "name2": "Baltimore" + }, + { + "x1": 646.35681, + "y1": 1128.5516, + "x2": 526.5687, + "y2": 1131.7183, + "name": null, + "name1": "Frederick Town", + "name2": "Fort Cumberland" + }, + { + "x1": 479.11158, + "y1": 1033.8876, + "x2": 481.27809, + "y2": 1094.6774, + "name": null, + "name1": "Pittsburgh", + "name2": "Fort Cumberland" + }, + { + "x1": 228.78524, + "y1": 1014.3049, + "x2": 440.57096, + "y2": 999.43028, + "name": null, + "name1": "Bassett Town", + "name2": "Pittsburgh" + }, + { + "x1": 518.94388, + "y1": 974.55593, + "x2": 562.69245, + "y2": 940.5152, + "name": null, + "name1": "Pittsburgh", + "name2": "Harrisburg" + }, + { + "x1": 619.31595, + "y1": 949.01496, + "x2": 628.64909, + "y2": 988.30569, + "name": null, + "name1": "Harrisburg", + "name2": "York" + }, + { + "x1": 663.85645, + "y1": 1006.0968, + "x2": 701.35537, + "y2": 969.8478600000001, + "name": null, + "name1": "York", + "name2": "Reading" + }, + { + "x1": 759.31202, + "y1": 949.84833, + "x2": 850.2562499999999, + "y2": 985.27606, + "name": null, + "name1": "Reading", + "name2": "Philadelphia" + }, + { + "x1": 908.63011, + "y1": 1030.8842, + "x2": 920.09917, + "y2": 1078.0530999999999, + "name": null, + "name1": "Philadelphia", + "name2": "Wilmington DE" + }, + { + "x1": 849.98819, + "y1": 1137.6914, + "x2": 886.79237, + "y2": 1129.1957, + "name": null, + "name1": "Baltimore", + "name2": "Wilmington DE" + }, + { + "x1": 920.40337, + "y1": 1023.0968, + "x2": 1003.9483, + "y2": 1088.1015, + "name": null, + "name1": "Philadelphia", + "name2": "Monmouth" + }, + { + "x1": 1017.8464, + "y1": 1017.1381, + "x2": 1033.8495, + "y2": 1070.3896, + "name": null, + "name1": "New Brunswick", + "name2": "Monmouth" + }, + { + "x1": 924.64522, + "y1": 988.37335, + "x2": 959.76472, + "y2": 981.72244, + "name": null, + "name1": "Philadelphia", + "name2": "New Brunswick" + }, + { + "x1": 930.01556, + "y1": 893.89157, + "x2": 978.18087, + "y2": 943.47351, + "name": null, + "name1": "Morristown", + "name2": "New Brunswick" + }, + { + "x1": 1023.785, + "y1": 945.87857, + "x2": 1045.4705999999999, + "y2": 913.01603, + "name": null, + "name1": "New Brunswick", + "name2": "New York" + }, + { + "x1": 1104.2595, + "y1": 880.08247, + "x2": 1148.1712, + "y2": 892.11777, + "name": null, + "name1": "New York", + "name2": "Long Island" + }, + { + "x1": 757.18708, + "y1": 913.72435, + "x2": 865.1994500000001, + "y2": 873.7064499999999, + "name": null, + "name1": "Reading", + "name2": "Morristown" + }, + { + "x1": 875.47542, + "y1": 846.43457, + "x2": 765.68563, + "y2": 792.2419600000001, + "name": null, + "name1": "Morristown", + "name2": "Wyoming Valley" + }, + { + "x1": 738.76731, + "y1": 823.40775, + "x2": 738.06503, + "y2": 897.7891099999999, + "name": null, + "name1": "Wyoming Valley", + "name2": "Reading" + }, + { + "x1": 631.8156, + "y1": 917.26592, + "x2": 685.64742, + "y2": 927.89062, + "name": null, + "name1": "Harrisburg", + "name2": "Reading" + }, + { + "x1": 472.16664, + "y1": 954.99649, + "x2": 513.40231, + "y2": 600.77474, + "name": null, + "name1": "Pittsburgh", + "name2": "Fort Niagara" + }, + { + "x1": 539.27641, + "y1": 576.31715, + "x2": 669.27295, + "y2": 609.48294, + "name": null, + "name1": "Fort Niagara", + "name2": "Genesee" + }, + { + "x1": 706.18851, + "y1": 658.02319, + "x2": 715.39658, + "y2": 749.39563, + "name": null, + "name1": "Genesee", + "name2": "Wyoming Valley" + }, + { + "x1": 132.80092, + "y1": 694.85067, + "x2": 461.55159, + "y2": 564.35025, + "name": null, + "name1": "Fort Detroit", + "name2": "Fort Niagara" + }, + { + "x1": 539.23485, + "y1": 548.69292, + "x2": 789.97769, + "y2": 496.6111, + "name": null, + "name1": "Fort Niagara", + "name2": "Oswego" + }, + { + "x1": 836.16704, + "y1": 488.73628, + "x2": 878.6646400000001, + "y2": 509.9893, + "name": null, + "name1": "Oswego", + "name2": "Fort Stanwix" + }, + { + "x1": 878.3123, + "y1": 537.08199, + "x2": 746.55996, + "y2": 607.91092, + "name": null, + "name1": "Fort Stanwix", + "name2": "Genesee" + }, + { + "x1": 957, + "y1": 560, + "x2": 991.63883, + "y2": 624.02415, + "name": null, + "name1": "Fort Stanwix", + "name2": "Albany" + }, + { + "x1": 1010.4299, + "y1": 624.89909, + "x2": 1022.0962999999999, + "y2": 570.90064, + "name": null, + "name1": "Albany", + "name2": "Saratoga" + }, + { + "x1": 1004.3885, + "y1": 700.522, + "x2": 999.43028, + "y2": 744.4374300000001, + "name": null, + "name1": "Albany", + "name2": "Westchester" + }, + { + "x1": 932.1405, + "y1": 839.35144, + "x2": 964.0133999999999, + "y2": 809.60347, + "name": null, + "name1": "Morristown", + "name2": "Westchester" + }, + { + "x1": 1023.5129, + "y1": 809.60227, + "x2": 1036.2685999999999, + "y2": 834.04814, + "name": null, + "name1": "Westchester", + "name2": "New York" + }, + { + "x1": 939.93195, + "y1": 871.22554, + "x2": 1024.9296, + "y2": 874.0588, + "name": null, + "name1": "Morristown", + "name2": "New York" + }, + { + "x1": 1086.554, + "y1": 834.75403, + "x2": 1104.9714000000001, + "y2": 805.7095599999999, + "name": null, + "name1": "New York", + "name2": "New Haven" + }, + { + "x1": 1031.3044, + "y1": 778.43648, + "x2": 1090.0944, + "y2": 774.89491, + "name": null, + "name1": "Westchester", + "name2": "New Haven" + }, + { + "x1": 1044.054, + "y1": 660.14813, + "x2": 1096.4692, + "y2": 660.85645, + "name": null, + "name1": "Albany", + "name2": "Springfield" + }, + { + "x1": 1175, + "y1": 699, + "x2": 1206.8827, + "y2": 748.06237, + "name": null, + "name1": "Springfield", + "name2": "Hartford" + }, + { + "x1": 1167.1178, + "y1": 782.06644, + "x2": 1185.6344, + "y2": 783.0435299999999, + "name": null, + "name1": "Hartford", + "name2": "Hartford" + }, + { + "x1": 1260.0896, + "y1": 777.72817, + "x2": 1292.672, + "y2": 777.01985, + "name": null, + "name1": "Hartford", + "name2": "Newport" + }, + { + "x1": 1302.6717, + "y1": 733.18767, + "x2": 1279.8807000000002, + "y2": 698.3136900000001, + "name": null, + "name1": "Newport", + "name2": "Lexington Concord" + }, + { + "x1": 1331.171, + "y1": 733.77117, + "x2": 1351.0039000000002, + "y2": 667.52295, + "name": null, + "name1": "Newport", + "name2": "Boston" + }, + { + "x1": 1296.7971, + "y1": 651.52331, + "x2": 1328.6711, + "y2": 640.35704, + "name": null, + "name1": "Lexington Concord", + "name2": "Boston" + }, + { + "x1": 1175.6754, + "y1": 664.60645, + "x2": 1217.9658000000002, + "y2": 664.8146399999999, + "name": null, + "name1": "Springfield", + "name2": "Lexington Concord" + }, + { + "x1": 1134.7598, + "y1": 561.23425, + "x2": 1131.1766, + "y2": 622.77415, + "name": null, + "name1": "Brattleboro", + "name2": "Springfield" + }, + { + "x1": 1394.6692, + "y1": 667.23127, + "x2": 1414.9186, + "y2": 707.23019, + "name": null, + "name1": "Boston", + "name2": "Barnstable" + }, + { + "x1": 1364.92, + "y1": 593.56667, + "x2": 1367.9199, + "y2": 485.77797000000004, + "name": null, + "name1": "Boston", + "name2": "Falmouth" + }, + { + "x1": 1338.8788, + "y1": 466.6535, + "x2": 1293.3386, + "y2": 488.06953, + "name": null, + "name1": "Falmouth", + "name2": "Concord" + }, + { + "x1": 1216.5493, + "y1": 512.27725, + "x2": 1181.9667, + "y2": 520.52701, + "name": null, + "name1": "Concord", + "name2": "Brattleboro" + }, + { + "x1": 1102.9274, + "y1": 532.27665, + "x2": 1072.3866, + "y2": 535.48497, + "name": null, + "name1": "Brattleboro", + "name2": "Saratoga" + }, + { + "x1": 1034.1376, + "y1": 433.48783, + "x2": 1035.5543, + "y2": 493.69446999999997, + "name": null, + "name1": "Ticonderoga", + "name2": "Saratoga" + }, + { + "x1": 1073.4544, + "y1": 390.62944, + "x2": 1126.5731, + "y2": 383.19275, + "name": null, + "name1": "Ticonderoga", + "name2": "Norwich" + }, + { + "x1": 1162.009, + "y1": 418.15493, + "x2": 1151.5095000000001, + "y2": 483.69482999999997, + "name": null, + "name1": "Norwich", + "name2": "Brattleboro" + }, + { + "x1": 1203.25, + "y1": 416.5, + "x2": 1232.1321, + "y2": 462.69531, + "name": null, + "name1": "Norwich", + "name2": "Concord" + }, + { + "x1": 1038.3875, + "y1": 237.28501, + "x2": 1037.6792, + "y2": 350.61516, + "name": null, + "name1": "Montreal", + "name2": "Ticonderoga" + }, + { + "x1": 1006.805, + "y1": 219.53548, + "x2": 828.01842, + "y2": 424.98807, + "name": null, + "name1": "Montreal", + "name2": "Oswego" + }, + { + "x1": 1073.095, + "y1": 174.99511, + "x2": 1130, + "y2": 122.25, + "name": null, + "name1": "Montreal", + "name2": "Quebec" + }, + { + "x1": 652.36158, + "y1": 1060.8876, + "x2": 670.77809, + "y2": 1096.1774, + "name": null, + "name1": "York", + "name2": "Frederick Town" + } + ], + "wilderness": [ + { + "x1": 90.648464, + "y1": 748.27474, + "x2": 167.28328, + "y2": 986.1757699999999, + "name": null, + "name1": "Fort Detroit", + "name2": "Bassett Town" + }, + { + "x1": 196.33447, + "y1": 1058.8038, + "x2": 170.79522, + "y2": 1212.0665999999999, + "name": null, + "name1": "Bassett Town", + "name2": "Point Pleasant" + }, + { + "x1": 1196, + "y1": 127, + "x2": 1346.2935, + "y2": 418.71331, + "name": "Quebec-Falmouth", + "name1": "Quebec", + "name2": "Falmouth" + } + ], + "sea": [ + { + "x1": 1040, + "y1": 195, + "x2": 1316.5, + "y2": 101.5, + "name": null, + "name1": "Montreal", + "name2": "Sea1" + }, + { + "x1": 1162.5, + "y1": 93.5, + "x2": 1316.5, + "y2": 101.5, + "name": null, + "name1": "Quebec", + "name2": "Sea1" + }, + { + "x1": 1374.0618, + "y1": 446.47501, + "x2": 1509.5, + "y2": 550, + "name": null, + "name1": "Falmouth", + "name2": "Sea2" + }, + { + "x1": 1367.5, + "y1": 629, + "x2": 1509.5, + "y2": 550, + "name": null, + "name1": "Boston", + "name2": "Sea2" + }, + { + "x1": 1434.3301, + "y1": 741.04565, + "x2": 1509.5, + "y2": 550, + "name": null, + "name1": "Barnstable", + "name2": "Sea2" + }, + { + "x1": 1330, + "y1": 772.5, + "x2": 1509.5, + "y2": 550, + "name": null, + "name1": "Newport", + "name2": "Sea2" + }, + { + "x1": 1186.3301, + "y1": 904.04565, + "x2": 1253.5, + "y2": 1016.5, + "name": null, + "name1": "Long Island", + "name2": "Sea3" + }, + { + "x1": 1128.0801, + "y1": 772.04565, + "x2": 1253.5, + "y2": 1016.5, + "name": null, + "name1": "New Haven", + "name2": "Sea3" + }, + { + "x1": 1064.5, + "y1": 874.5, + "x2": 1253.5, + "y2": 1016.5, + "name": null, + "name1": "New York", + "name2": "Sea3" + }, + { + "x1": 926, + "y1": 1116.5, + "x2": 1097.5, + "y2": 1210.5, + "name": null, + "name1": "Wilmington DE", + "name2": "Sea4" + }, + { + "x1": 886, + "y1": 997.5, + "x2": 1097.5, + "y2": 1210.5, + "name": null, + "name1": "Philadelphia", + "name2": "Sea4" + }, + { + "x1": 810.5, + "y1": 1142.5, + "x2": 986.5, + "y2": 1430.5, + "name": null, + "name1": "Baltimore", + "name2": "Sea5" + }, + { + "x1": 693.5, + "y1": 1254, + "x2": 986.5, + "y2": 1430.5, + "name": null, + "name1": "Alexandria", + "name2": "Sea5" + }, + { + "x1": 806.62952, + "y1": 1352.5383, + "x2": 986.5, + "y2": 1430.5, + "name": null, + "name1": "Yorktown", + "name2": "Sea5" + }, + { + "x1": 822, + "y1": 1487.5, + "x2": 986.5, + "y2": 1430.5, + "name": null, + "name1": "Norfolk", + "name2": "Sea5" + }, + { + "x1": 803.8092, + "y1": 1706.0598, + "x2": 677.5, + "y2": 2063.5, + "name": null, + "name1": "New Bern", + "name2": "Sea6" + }, + { + "x1": 715.5592, + "y1": 1852.3098, + "x2": 677.5, + "y2": 2063.5, + "name": null, + "name1": "Wilmington", + "name2": "Sea6" + }, + { + "x1": 484, + "y1": 2086, + "x2": 677.5, + "y2": 2063.5, + "name": null, + "name1": "Charleston", + "name2": "Sea6" + }, + { + "x1": 267, + "y1": 2307, + "x2": 399.5, + "y2": 2393.5, + "name": null, + "name1": "Savannah", + "name2": "Sea7" + }, + { + "x1": 220.5, + "y1": 2429.5, + "x2": 399.5, + "y2": 2393.5, + "name": null, + "name1": "St. Mary's", + "name2": "Sea7" + } + ], + "colony": [ + { + "x1": 1250.8815, + "y1": 498.65267, + "x2": 1503.0411, + "y2": 1042.6374, + "name": null, + "name1": "Concord", + "name2": "NH" + }, + { + "x1": 1136.1348, + "y1": 519.90207, + "x2": 1503.0411, + "y2": 1042.6374, + "name": null, + "name1": "Brattleboro", + "name2": "NH" + }, + { + "x1": 1172.9671, + "y1": 382.48926, + "x2": 1503.0411000000001, + "y2": 1042.6374, + "name": null, + "name1": "Norwich", + "name2": "NH" + }, + { + "x1": 1537.0402, + "y1": 1120.5519, + "x2": 1138.968, + "y2": 660.14813, + "name": null, + "name1": "MA", + "name2": "Springfield" + }, + { + "x1": 1255.1314, + "y1": 671.48115, + "x2": 1537.0402, + "y2": 1120.5519, + "name": null, + "name1": "Lexington Concord", + "name2": "MA" + }, + { + "x1": 1437.8763, + "y1": 745.14575, + "x2": 1537.0402, + "y2": 1120.5519, + "name": null, + "name1": "Barnstable", + "name2": "MA" + }, + { + "x1": 1365.6283, + "y1": 633.23222, + "x2": 1537.0402000000001, + "y2": 1120.5519, + "name": null, + "name1": "Boston", + "name2": "MA" + }, + { + "x1": 1365.6283, + "y1": 437.73771, + "x2": 1537.0402000000001, + "y2": 1120.5519, + "name": null, + "name1": "Falmouth", + "name2": "MA" + }, + { + "x1": 1333.0459, + "y1": 770.64503, + "x2": 1576.7057, + "y2": 1192.7998, + "name": null, + "name1": "Newport", + "name2": "RI" + }, + { + "x1": 1212.6326, + "y1": 780.56142, + "x2": 1503.0411, + "y2": 1197.0497, + "name": null, + "name1": "Hartford", + "name2": "CT" + }, + { + "x1": 1126.2184, + "y1": 772.06166, + "x2": 1503.0411, + "y2": 1197.0497, + "name": null, + "name1": "New Haven", + "name2": "CT" + }, + { + "x1": 1408.5453, + "y1": 1122.5186, + "x2": 1058.6385, + "y2": 878.85875, + "name": null, + "name1": "NY", + "name2": "New York" + }, + { + "x1": 1416.6269, + "y1": 1116.302, + "x2": 987.38895, + "y2": 781.97805, + "name": null, + "name1": "NY", + "name2": "Westchester" + }, + { + "x1": 1002.9718, + "y1": 665.81464, + "x2": 1416.6269, + "y2": 1116.302, + "name": null, + "name1": "Albany", + "name2": "NY" + }, + { + "x1": 1031.3044, + "y1": 535.48497, + "x2": 1416.6269, + "y2": 1116.302, + "name": null, + "name1": "Saratoga", + "name2": "NY" + }, + { + "x1": 1034.1376, + "y1": 390.98902, + "x2": 1416.6269, + "y2": 1116.302, + "name": null, + "name1": "Ticonderoga", + "name2": "NY" + }, + { + "x1": 913.72435, + "y1": 511.40231, + "x2": 1416.6269, + "y2": 1116.302, + "name": null, + "name1": "Fort Stanwix", + "name2": "NY" + }, + { + "x1": 807.47733, + "y1": 461.82037, + "x2": 1416.6269, + "y2": 1116.302, + "name": null, + "name1": "Oswego", + "name2": "NY" + }, + { + "x1": 708.31345, + "y1": 623.31583, + "x2": 1416.6269, + "y2": 1116.302, + "name": null, + "name1": "Genesee", + "name2": "NY" + }, + { + "x1": 488.73628, + "y1": 558.151, + "x2": 1416.6269, + "y2": 1116.302, + "name": null, + "name1": "Fort Niagara", + "name2": "NY" + }, + { + "x1": 83.580987, + "y1": 716.81321, + "x2": 1418.0435, + "y2": 1001.5552, + "name": null, + "name1": "Fort Detroit", + "name2": "Canada" + }, + { + "x1": 1415.2103, + "y1": 1226.7989, + "x2": 903.80796, + "y2": 859.89253, + "name": null, + "name1": "NJ", + "name2": "Morristown" + }, + { + "x1": 993.05545, + "y1": 970.38942, + "x2": 1415.2103, + "y2": 1226.7989, + "name": null, + "name1": "New Brunswick", + "name2": "NJ" + }, + { + "x1": 1045.4706, + "y1": 1114.8854, + "x2": 1415.2103000000002, + "y2": 1226.7988999999998, + "name": null, + "name1": "Monmouth", + "name2": "NJ" + }, + { + "x1": 1345.7956, + "y1": 1233.882, + "x2": 716.81321, + "y2": 934.97375, + "name": null, + "name1": "PA", + "name2": "Reading" + }, + { + "x1": 1345.7956, + "y1": 1233.882, + "x2": 628.98234, + "y2": 1031.3044, + "name": null, + "name1": "PA", + "name2": "York" + }, + { + "x1": 594.9833, + "y1": 912.30772, + "x2": 1345.7956, + "y2": 1233.882, + "name": null, + "name1": "Harrisburg", + "name2": "PA" + }, + { + "x1": 722.47972, + "y1": 784.8113, + "x2": 1345.7956, + "y2": 1233.882, + "name": null, + "name1": "Wyoming Valley", + "name2": "PA" + }, + { + "x1": 470.32013, + "y1": 995.88871, + "x2": 1345.7956, + "y2": 1233.882, + "name": null, + "name1": "Pittsburgh", + "name2": "PA" + }, + { + "x1": 179.91162, + "y1": 1025.6379, + "x2": 1345.7956, + "y2": 1233.882, + "name": null, + "name1": "Bassett Town", + "name2": "PA" + }, + { + "x1": 925.57679, + "y1": 1115.901, + "x2": 1425.4283, + "y2": 1302.2184, + "name": null, + "name1": "Wilmington DE", + "name2": "DE" + }, + { + "x1": 1333.2713, + "y1": 1315.2406, + "x2": 804.37031, + "y2": 1143.9488, + "name": null, + "name1": "MD", + "name2": "Baltimore" + }, + { + "x1": 672.14505, + "y1": 1127.9215, + "x2": 1333.2712999999999, + "y2": 1315.2405999999999, + "name": null, + "name1": "Frederick Town", + "name2": "MD" + }, + { + "x1": 478.8157, + "y1": 1132.93, + "x2": 1333.2712999999999, + "y2": 1315.2406, + "name": null, + "name1": "Fort Cumberland", + "name2": "MD" + }, + { + "x1": 805.37201, + "y1": 1355.3089, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Yorktown", + "name2": "VA" + }, + { + "x1": 820.39761, + "y1": 1484.529, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Norfolk", + "name2": "VA" + }, + { + "x1": 672.14505, + "y1": 1480.5222, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Petersburg", + "name2": "VA" + }, + { + "x1": 643.09556, + "y1": 1356.3106, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Richmond", + "name2": "VA" + }, + { + "x1": 695.1843, + "y1": 1262.1502, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Alexandria", + "name2": "VA" + }, + { + "x1": 479.81741, + "y1": 1295.2065, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Charlottesville", + "name2": "VA" + }, + { + "x1": 527.89932, + "y1": 1483.5273, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Lynch's Ferry", + "name2": "VA" + }, + { + "x1": 388.66212, + "y1": 1440.4539, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Fincastle", + "name2": "VA" + }, + { + "x1": 248.42321, + "y1": 1450.471, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Fort Chiswell", + "name2": "VA" + }, + { + "x1": 166.28328, + "y1": 1249.128, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Point Pleasant", + "name2": "VA" + }, + { + "x1": 97.165529, + "y1": 1485.5307, + "x2": 1279.1792, + "y2": 1372.3379, + "name": null, + "name1": "Abingdon", + "name2": "VA" + }, + { + "x1": 162.27645, + "y1": 1606.7372, + "x2": 1301.2167, + "y2": 1441.4556, + "name": null, + "name1": "Gilbert Town", + "name2": "NC" + }, + { + "x1": 335.57167, + "y1": 1597.7218, + "x2": 1301.2167, + "y2": 1441.4556, + "name": null, + "name1": "Salem", + "name2": "NC" + }, + { + "x1": 244.41638, + "y1": 1691.8823, + "x2": 1301.2167, + "y2": 1441.4556, + "name": null, + "name1": "Charlotte", + "name2": "NC" + }, + { + "x1": 517.88225, + "y1": 1624.7679, + "x2": 1301.2167, + "y2": 1441.4556, + "name": null, + "name1": "Hillsboro", + "name2": "NC" + }, + { + "x1": 646.10068, + "y1": 1711.9164, + "x2": 1301.2167, + "y2": 1441.4556, + "name": null, + "name1": "Wake (Raleigh)", + "name2": "NC" + }, + { + "x1": 802.36689, + "y1": 1711.9164, + "x2": 1301.2167, + "y2": 1441.4556, + "name": null, + "name1": "New Bern", + "name2": "NC" + }, + { + "x1": 713.21502, + "y1": 1850.1519, + "x2": 1301.2167, + "y2": 1441.4556, + "name": null, + "name1": "Wilmington", + "name2": "NC" + }, + { + "x1": 1258.1433, + "y1": 1528.6041, + "x2": 615.04778, + "y2": 1957.3345, + "name": null, + "name1": "SC", + "name2": "Georgetown" + }, + { + "x1": 482.82253, + "y1": 2090.5614, + "x2": 1258.1433, + "y2": 1528.6041, + "name": null, + "name1": "Charleston", + "name2": "SC" + }, + { + "x1": 442.75427, + "y1": 1942.3089, + "x2": 1258.1433, + "y2": 1528.6041, + "name": null, + "name1": "Eutaw Springs", + "name2": "SC" + }, + { + "x1": 534.91126, + "y1": 1833.1229, + "x2": 1258.1433, + "y2": 1528.6041, + "name": null, + "name1": "Cheraw", + "name2": "SC" + }, + { + "x1": 379.64676, + "y1": 1809.0819, + "x2": 1258.1433, + "y2": 1528.6041, + "name": null, + "name1": "Camden", + "name2": "SC" + }, + { + "x1": 257.43857, + "y1": 1972.3601, + "x2": 1258.1433, + "y2": 1528.6041, + "name": null, + "name1": "Ninety Six", + "name2": "SC" + }, + { + "x1": 114.19454, + "y1": 1813.0887, + "x2": 1258.1433, + "y2": 1528.6041, + "name": null, + "name1": "Fort Prince George", + "name2": "SC" + }, + { + "x1": 173.29522, + "y1": 2094.5683, + "x2": 1208.058, + "y2": 1596.7201, + "name": null, + "name1": "Augusta", + "name2": "GA" + }, + { + "x1": 266.45392, + "y1": 2315.9454, + "x2": 1208.058, + "y2": 1596.7201, + "name": null, + "name1": "Savannah", + "name2": "GA" + }, + { + "x1": 220.37543, + "y1": 2437.1519, + "x2": 1208.058, + "y2": 1596.7201, + "name": null, + "name1": "St. Mary's", + "name2": "GA" + }, + { + "x1": 1408.5453, + "y1": 1122.5186, + "x2": 1186.3301, + "y2": 904.04565, + "name": null, + "name1": "NY", + "name2": "Long Island" + }, + { + "x1": 886, + "y1": 997.5, + "x2": 1345.7956, + "y2": 1233.882, + "name": null, + "name1": "Philadelphia", + "name2": "PA" + }, + { + "x1": 1162.5, + "y1": 93.5, + "x2": 1418.0435, + "y2": 1001.5552, + "name": null, + "name1": "Quebec", + "name2": "Canada" + }, + { + "x1": 1040, + "y1": 195, + "x2": 1418.0435, + "y2": 1001.5552, + "name": null, + "name1": "Montreal", + "name2": "Canada" + } + ] + }, + "labels": [ + { + "x": 1527.1014, + "y": 2281.8875, + "name": "9" + }, + { + "x": 1468.5017, + "y": 2409.605, + "name": "1783" + }, + { + "x": 1399.8848, + "y": 2412.6101, + "name": "1782" + }, + { + "x": 1329.2645, + "y": 2408.6033, + "name": "1781" + }, + { + "x": 1265.1553, + "y": 2410.1057, + "name": "1780" + }, + { + "x": 1201.0461, + "y": 2410.1057, + "name": "1779" + }, + { + "x": 1138.4395, + "y": 2409.605, + "name": "1778" + }, + { + "x": 1062.8105, + "y": 2408.1025, + "name": "1777" + }, + { + "x": 998.2005, + "y": 2408.6033, + "name": "1776" + }, + { + "x": 928.08105, + "y": 2411.1077, + "name": "1775" + }, + { + "x": 1476.0145, + "y": 2284.8926, + "name": "8" + }, + { + "x": 1416.9138, + "y": 2286.896, + "name": "7" + }, + { + "x": 1342.2867, + "y": 2285.3933, + "name": "6" + }, + { + "x": 1264.6544, + "y": 2282.3882, + "name": "5" + }, + { + "x": 1213.5674, + "y": 2279.884, + "name": "4" + }, + { + "x": 1144.4497, + "y": 2280.3848, + "name": "3" + }, + { + "x": 1082.3439, + "y": 2282.3882, + "name": "2" + }, + { + "x": 1004.2108, + "y": 2285.8943, + "name": "1" + }, + { + "x": 932.08789, + "y": 2283.8909, + "name": "0" + }, + { + "x": 166.09312, + "y": 365.55655, + "name": "French Reinforcements" + }, + { + "x": 395.46118, + "y": 363.54544, + "name": "American Leader Reinforcements" + }, + { + "x": 1308.392, + "y": 100.05029, + "name": "Sea1" + }, + { + "x": 1503.4926, + "y": 111.18933, + "name": "Captured Generals" + }, + { + "x": 1155, + "y": 95, + "name": "Quebec" + }, + { + "x": 1030, + "y": 200, + "name": "Montreal" + }, + { + "x": 1170, + "y": 380, + "name": "Norwich" + }, + { + "x": 1030, + "y": 400, + "name": "Ticonderoga" + }, + { + "x": 815, + "y": 470, + "name": "Oswego" + }, + { + "x": 910, + "y": 515, + "name": "Fort Stanwix" + }, + { + "x": 1025, + "y": 540, + "name": "Saratoga" + }, + { + "x": 1145, + "y": 535, + "name": "Brattleboro" + }, + { + "x": 1240, + "y": 500, + "name": "Concord" + }, + { + "x": 1363.8234, + "y": 463.28925, + "name": "Falmouth" + }, + { + "x": 1363.3225, + "y": 632.07678, + "name": "Boston" + }, + { + "x": 1428.9343, + "y": 738.75854, + "name": "Barnstable" + }, + { + "x": 1330, + "y": 772.5, + "name": "Newport" + }, + { + "x": 1254.1365, + "y": 673.64758, + "name": "Lexington Concord" + }, + { + "x": 1215.0699, + "y": 800.36346, + "name": "Hartford" + }, + { + "x": 1110.3916, + "y": 778.82678, + "name": "New Haven" + }, + { + "x": 1121.9113, + "y": 655.61688, + "name": "Springfield" + }, + { + "x": 997.19879, + "y": 667.63739, + "name": "Albany" + }, + { + "x": 989.18512, + "y": 794.85413, + "name": "Westchester" + }, + { + "x": 1057.802, + "y": 875.99231, + "name": "New York" + }, + { + "x": 1188.0239, + "y": 912.55463, + "name": "Long Island" + }, + { + "x": 1001.3301, + "y": 977.54565, + "name": "New Brunswick" + }, + { + "x": 1033.7611, + "y": 1103.8805, + "name": "Monmouth" + }, + { + "x": 893.0213, + "y": 871.98547, + "name": "Morristown" + }, + { + "x": 715.7193, + "y": 630.07336, + "name": "Genesee" + }, + { + "x": 501.56177, + "y": 561.97504, + "name": "Fort Niagara" + }, + { + "x": 83.14164, + "y": 710.2099, + "name": "Fort Detroit" + }, + { + "x": 181.30887, + "y": 1032.7594, + "name": "Bassett Town" + }, + { + "x": 471.30289, + "y": 1001.2056, + "name": "Pittsburgh" + }, + { + "x": 598.0188, + "y": 923.07251, + "name": "Harrisburg" + }, + { + "x": 723.75372, + "y": 936.08838, + "name": "Reading" + }, + { + "x": 624.56396, + "y": 1030.756, + "name": "York" + }, + { + "x": 718.72443, + "y": 786.84045, + "name": "Wyoming Valley" + }, + { + "x": 872.98718, + "y": 1009.2193, + "name": "Philadelphia" + }, + { + "x": 909.04865, + "y": 1123.4138, + "name": "Wilmington DE" + }, + { + "x": 800.36346, + "y": 1153.465, + "name": "Baltimore" + }, + { + "x": 661.62714, + "y": 1143.448, + "name": "Frederick Town" + }, + { + "x": 682.16211, + "y": 1260.1469, + "name": "Alexandria" + }, + { + "x": 467.79694, + "y": 1297.21, + "name": "Charlottesville" + }, + { + "x": 636.08362, + "y": 1367.8302, + "name": "Richmond" + }, + { + "x": 808.37714, + "y": 1357.3123, + "name": "Yorktown" + }, + { + "x": 819.89679, + "y": 1495.5479, + "name": "Norfolk" + }, + { + "x": 660.62543, + "y": 1496.5496, + "name": "Petersburg" + }, + { + "x": 512.87372, + "y": 1485.5306, + "name": "Lynch's Ferry" + }, + { + "x": 386.15784, + "y": 1446.4642, + "name": "Fincastle" + }, + { + "x": 237.90529, + "y": 1447.9667, + "name": "Fort Chiswell" + }, + { + "x": 160.7739, + "y": 1260.1469, + "name": "Point Pleasant" + }, + { + "x": 91.656143, + "y": 1496.5496, + "name": "Abingdon" + }, + { + "x": 162.8092, + "y": 1603.8098, + "name": "Gilbert Town" + }, + { + "x": 341.58191, + "y": 1604.7338, + "name": "Salem" + }, + { + "x": 514.87714, + "y": 1625.2688, + "name": "Hillsboro" + }, + { + "x": 646.3092, + "y": 1707.0598, + "name": "Wake (Raleigh)" + }, + { + "x": 815.88995, + "y": 1717.4258, + "name": "New Bern" + }, + { + "x": 713.71588, + "y": 1857.1638, + "name": "Wilmington" + }, + { + "x": 605.0307, + "y": 1954.3293, + "name": "Georgetown" + }, + { + "x": 523.89252, + "y": 1833.6237, + "name": "Cheraw" + }, + { + "x": 368.62799, + "y": 1816.5947, + "name": "Camden" + }, + { + "x": 249.42491, + "y": 1701.8993, + "name": "Charlotte" + }, + { + "x": 110.68857, + "y": 1818.5981, + "name": "Fort Prince George" + }, + { + "x": 252.93089, + "y": 1970.8575, + "name": "Ninety Six" + }, + { + "x": 434.7406, + "y": 1951.3242, + "name": "Eutaw Springs" + }, + { + "x": 478.8157, + "y": 2099.0759, + "name": "Charleston" + }, + { + "x": 264.4505, + "y": 2315.4446, + "name": "Savannah" + }, + { + "x": 179.8063, + "y": 2104.0845, + "name": "Augusta" + }, + { + "x": 215.3669, + "y": 2438.6543, + "name": "St. Mary's" + }, + { + "x": 1008.5179, + "y": 2050.7935, + "name": "BRC" + }, + { + "x": 1231.9423, + "y": 2050.9939, + "name": "ARC1" + }, + { + "x": 1466.2352, + "y": 2057.8745, + "name": "ARC2" + }, + { + "x": 1465, + "y": 1776, + "name": "British Reinforcement Box" + }, + { + "x": 1167.4889, + "y": 1789.0479, + "name": "War Ends Card" + }, + { + "x": 1197.0392, + "y": 1587.2039, + "name": "GA" + }, + { + "x": 1252.1331, + "y": 1520.0896, + "name": "SC" + }, + { + "x": 1300, + "y": 1443.5, + "name": "NC" + }, + { + "x": 1290.6989, + "y": 1383.3567, + "name": "VA" + }, + { + "x": 1339, + "y": 1302.5, + "name": "MD" + }, + { + "x": 1407.3976, + "y": 1313.7382, + "name": "DE" + }, + { + "x": 1414.9104, + "y": 1234.1024, + "name": "NJ" + }, + { + "x": 1339, + "y": 1230, + "name": "PA" + }, + { + "x": 1504.0623, + "y": 1195.0358, + "name": "CT" + }, + { + "x": 1577.6877, + "y": 1194.535, + "name": "RI" + }, + { + "x": 1534.1135, + "y": 1122.913, + "name": "MA" + }, + { + "x": 1406.8969, + "y": 1122.4121, + "name": "NY" + }, + { + "x": 1498, + "y": 1043, + "name": "NH" + }, + { + "x": 1416, + "y": 1003.5, + "name": "Canada" + }, + { + "x": 1509.5, + "y": 550, + "name": "Sea2" + }, + { + "x": 1253.5, + "y": 1016.5, + "name": "Sea3" + }, + { + "x": 1088.8549, + "y": 1218.0751, + "name": "Sea4" + }, + { + "x": 981.17151, + "y": 1441.9565, + "name": "Sea5" + }, + { + "x": 671.14337, + "y": 2067.0212, + "name": "Sea6" + }, + { + "x": 393.67065, + "y": 2394.5793, + "name": "Sea7" + }, + { + "x": 585, + "y": 385, + "name": "Continental Corgress Dispersed Box" + }, + { + "x": 479.92914, + "y": 1140.5603, + "name": "Fort Cumberland" + } + ] +}
\ No newline at end of file diff --git a/tools/layout.svg b/tools/layout.svg index 506d903..9805857 100644 --- a/tools/layout.svg +++ b/tools/layout.svg @@ -40,9 +40,9 @@ inkscape:window-height="480" id="namedview8" showgrid="false" - inkscape:zoom="0.5" - inkscape:cx="1894.5029" - inkscape:cy="1424.4221" + inkscape:zoom="0.71155804" + inkscape:cx="871.00863" + inkscape:cy="553.26207" inkscape:current-layer="svg6" inkscape:snap-center="false" inkscape:snap-others="true" @@ -55,31 +55,32 @@ <image sodipodi:absref="/home/tor/src/rally/public/washingtons-war/tools/mapmask.png" xlink:href="mapmask.png" - x="0" - y="0" - width="1650" - height="2550" - image-rendering="pixelated" - sodipodi:insensitive="true" + style="display:inline" id="image2" - style="display:inline" /> + sodipodi:insensitive="true" + image-rendering="pixelated" + height="2550" + width="1650" + y="0" + x="0" /> <image sodipodi:absref="/home/tor/src/rally/public/washingtons-war/tools/map75.png" xlink:href="map75.png" - x="0" - y="0" - width="1650" - height="2550" - image-rendering="pixelated" - opacity="0.535871" - id="image4" - style="display:inline" + sodipodi:insensitive="true" inkscape:label="texture" - sodipodi:insensitive="true" /> + style="display:inline" + id="image4" + opacity="0.535871" + image-rendering="pixelated" + height="2550" + width="1650" + y="0" + x="0" /> <g id="g2693" - inkscape:label="fortress" - style="display:none"> + inkscape:label="fortified_port" + style="display:none" + sodipodi:insensitive="true"> <rect style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" id="rect887" @@ -112,7 +113,8 @@ <g id="g2712" inkscape:label="winter_quarters" - style="display:none"> + style="display:none" + sodipodi:insensitive="true"> <rect style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" id="rect845" @@ -235,8 +237,9 @@ </g> <g id="g2687" - inkscape:label="space" - style="display:none"> + inkscape:label="regular" + style="display:none" + sodipodi:insensitive="true"> <circle style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" id="circle910" @@ -587,7 +590,8 @@ <g id="g2555" inkscape:label="sea" - style="display:inline"> + style="display:inline" + sodipodi:insensitive="true"> <rect style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" id="rect1000" @@ -641,7 +645,8 @@ <g id="g2546" inkscape:label="colony" - style="display:inline"> + style="display:inline" + sodipodi:insensitive="true"> <rect style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" id="rect1016" @@ -744,85 +749,83 @@ <g id="g2584" inkscape:label="box" - style="display:inline" - sodipodi:insensitive="true"> + style="display:inline"> + <rect + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:2.99946" + id="rect1092" + width="214" + height="206" + x="1358" + y="1673" + inkscape:label="British Reinforcement Box" /> + <rect + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3.00286" + id="rect1096" + width="214" + height="206" + x="294" + y="258" + inkscape:label="American Leader Reinforcements" /> + <rect + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3.08098" + id="rect1098" + width="214" + height="207" + x="63" + y="258" + inkscape:label="French Reinforcements" /> <rect style="opacity:1;fill:#000000;fill-opacity:0.46748;stroke:none;stroke-width:3" id="rect1606" width="88" height="104" x="542" - y="332" /> + y="332" + inkscape:label="Continental Congress Dispersed" /> <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1044" - width="64" - height="71" - x="905" - y="2241" /> - <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1046" - width="64" - height="71" - x="971" - y="2241" /> - <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1048" - width="64" - height="71" - x="1037" - y="2241" /> - <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1050" - width="64" - height="71" - x="1103" - y="2241" /> - <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1052" - width="65" - height="71" - x="1169" - y="2241" /> - <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1054" - width="64" - height="71" - x="1236" - y="2241" /> + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3.23342" + id="rect1094" + width="205" + height="136" + x="1400" + y="46" + inkscape:label="Captured Generals" /> + </g> + <g + id="g607" + inkscape:label="Card Boxes"> <rect style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1056" - width="64" - height="71" - x="1302" - y="2241" /> + id="rect1084" + width="199" + height="277" + x="904" + y="1915" /> <rect style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1058" - width="64" - height="71" - x="1368" - y="2241" /> + id="rect1086" + width="199" + height="277" + x="1137" + y="1915" /> <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1060" - width="65" - height="71" - x="1434" - y="2241" /> + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:2.97641" + id="rect1088" + width="199.00003" + height="277" + x="1370" + y="1915" /> <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1062" - width="63" - height="71" - x="1501" - y="2241" /> + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3.0365" + id="rect1090" + width="278" + height="198.99998" + x="1027" + y="1679" /> + </g> + <g + id="g580" + inkscape:label="Game Turn"> <rect style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" id="rect1066" @@ -886,62 +889,80 @@ height="72" x="1433" y="2368" /> + </g> + <g + id="g569" + inkscape:label="French Alliance Track"> <rect style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1084" - width="199" - height="277" - x="904" - y="1915" /> + id="rect1044" + width="64" + height="71" + x="905" + y="2241" /> <rect style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" - id="rect1086" - width="199" - height="277" - x="1137" - y="1915" /> + id="rect1046" + width="64" + height="71" + x="971" + y="2241" /> <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:2.97641" - id="rect1088" - width="199.00003" - height="277" - x="1370" - y="1915" /> + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" + id="rect1048" + width="64" + height="71" + x="1037" + y="2241" /> <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3.0365" - id="rect1090" - width="278" - height="198.99998" - x="1027" - y="1679" /> + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" + id="rect1050" + width="64" + height="71" + x="1103" + y="2241" /> <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:2.99946" - id="rect1092" - width="214" - height="206" - x="1358" - y="1673" /> + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" + id="rect1052" + width="65" + height="71" + x="1169" + y="2241" /> <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3.23342" - id="rect1094" - width="205" - height="136" - x="1400" - y="46" /> + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" + id="rect1054" + width="64" + height="71" + x="1236" + y="2241" /> <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3.00286" - id="rect1096" - width="214" - height="206" - x="294" - y="258" /> + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" + id="rect1056" + width="64" + height="71" + x="1302" + y="2241" /> <rect - style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3.08098" - id="rect1098" - width="214" - height="207" - x="63" - y="258" /> + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" + id="rect1058" + width="64" + height="71" + x="1368" + y="2241" /> + <rect + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" + id="rect1060" + width="65" + height="71" + x="1434" + y="2241" /> + <rect + style="opacity:0.99;fill:#ff0000;fill-opacity:0.46748;stroke:none;stroke-width:3" + id="rect1062" + width="63" + height="71" + x="1501" + y="2241" /> </g> <g id="g2117" @@ -1202,36 +1223,43 @@ sodipodi:nodetypes="cc" /> <path style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 759.31202,949.84833 92.08074,31.1658" - id="path1918" /> + d="m 759.31202,949.84833 90.94423,35.42773" + id="path1918" + sodipodi:nodetypes="cc" /> <path style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 905.22459,1026.3462 1.41662,2.8332 13.45796,48.8737" - id="path1920" /> + d="m 908.63011,1030.8842 11.46906,47.1689" + id="path1920" + sodipodi:nodetypes="cc" /> <path style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 845.72626,1138.2597 46.74868,-9.9164" - id="path1922" /> + d="m 849.98819,1137.6914 36.80418,-8.4957" + id="path1922" + sodipodi:nodetypes="cc" /> <path style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 913.01603,1019.9714 96.33067,71.5396" - id="path1924" /> + d="m 920.40337,1023.0968 83.54493,65.0047" + id="path1924" + sodipodi:nodetypes="cc" /> <path style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 1017.8464,1017.1381 17.7079,58.0817" - id="path1926" /> + d="m 1017.8464,1017.1381 16.0031,53.2515" + id="path1926" + sodipodi:nodetypes="cc" /> <path style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 920.09917,990.93051 39.66555,-9.20807" - id="path1928" /> + d="m 924.64522,988.37335 35.1195,-6.65091" + id="path1928" + sodipodi:nodetypes="cc" /> <path style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 930.01556,893.89157 48.16531,49.58194" id="path1930" /> <path style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" - d="m 1027.7628,947.01508 17.7078,-33.99905" - id="path1932" /> + d="m 1023.785,945.87857 21.6856,-32.86254" + id="path1932" + sodipodi:nodetypes="cc" /> <path style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" d="m 1104.2595,880.08247 43.9117,12.0353" @@ -1451,7 +1479,8 @@ style="opacity:1;fill:none;fill-opacity:0.46748;stroke:#000000;stroke-width:5;stroke-miterlimit:4;stroke-dasharray:5, 5;stroke-dashoffset:0;stroke-opacity:1" d="m 1196,127 c 74.0155,102.10344 61.3742,165.34334 150.2935,291.71331" id="path2123" - sodipodi:nodetypes="cc" /> + sodipodi:nodetypes="cc" + inkscape:label="Quebec-Falmouth" /> </g> <g id="g2298" @@ -1542,7 +1571,8 @@ <g id="g2530" inkscape:label="colony" - style="display:none"> + style="display:none" + sodipodi:insensitive="true"> <path style="opacity:1;fill:none;fill-opacity:1;stroke:#f50000;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:3, 3;stroke-dashoffset:0;stroke-opacity:1" d="m 1250.8815,498.65267 252.1596,543.98473" @@ -1816,7 +1846,8 @@ <g id="g1810" inkscape:label="labels" - style="display:none"> + style="display:inline" + sodipodi:insensitive="true"> <text xml:space="preserve" style="font-size:14px;font-family:sans-serif;-inkscape-font-specification:sans-serif;opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:12, 6, 3, 6;stroke-dashoffset:0;stroke-opacity:1" @@ -2406,7 +2437,7 @@ sodipodi:role="line" id="tspan1376" x="909.04865" - y="1123.4138">Wilmington</tspan></text> + y="1123.4138">Wilmington DE</tspan></text> <text xml:space="preserve" style="font-size:14px;font-family:sans-serif;-inkscape-font-specification:sans-serif;opacity:1;fill:#000000;fill-opacity:0.46748;stroke:none;stroke-width:3" 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") +*/ diff --git a/tools/parse-layout.js b/tools/parse-layout.js index b382849..6f77adf 100644 --- a/tools/parse-layout.js +++ b/tools/parse-layout.js @@ -1,61 +1,30 @@ "use strict" -/* COMMON PARSING */ - const fs = require("fs") let points = {} -let circles = {} -let rects = {} +let boxes = {} let edges = {} +let mode, group, name, x, y, w, h, cx, cy, rx, ry, x2, y2 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) -} +let labels_uniq = {} 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}) + if (!(group in points)) + points[group] = [] + points[group].push({x,y,name}) } function add_rect(x, y, w, h) { - if (!(name in rects)) - rects[name] = [] - rects[name].push({x,y,w,h}) + if (!(group in boxes)) + boxes[group] = [] + boxes[group].push({x,y,w,h,name}) } function add_edge(x1, y1, x2, y2) { - if (!(name in edges)) - edges[name] = [] - edges[name].push({x1,y1,x2,y2}) + if (!(group in edges)) + edges[group] = [] + edges[group].push({x1,y1,x2,y2,name}) } function flush() { @@ -64,13 +33,14 @@ function flush() { } if (mode === 'rect') { add_rect(x, y, w, h) - add_point(x + w/2, y + h/2) + add_point( x + w/2, y + h/2 ) } if (mode === 'circle') { - add_circle(cx, cy, rx, ry) - add_point(cx, cy) + add_rect(cx - rx, cy - ry, rx * 2, ry * 2) + add_point( cx, cy ) } x = y = x2 = y2 = w = h = cx = cy = rx = ry = 0 + name = null } function parse_path_data(path) { @@ -184,18 +154,23 @@ for (let line of fs.readFileSync("tools/layout.svg", "utf-8").split("\n")) { else if (line.startsWith('ry="')) ry = (Number(line.split('"')[1])) else if (line.startsWith('inkscape:label="') && mode === "g") + group = 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.*/, "") + if (name in labels_uniq) + console.log("DUPLICATE LABEL", name) labels.push({x, y, name}) + labels_uniq[name] = 1 } } flush() -function find_closest_label(x, y) { +function find_label(x, y, limit) { let nd = Infinity, nn = null for (let n of labels) { @@ -206,261 +181,35 @@ function find_closest_label(x, y) { } } - if (!nn) { - console.log("NOT FOUND", x, y) - return null - } - - if (nd > 50) { - console.log("NO LABEL", x, y, nd) + if (!nn || nd > limit) { + console.log("LABEL NOT FOUND", x, y) 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 +for (let group in points) { + for (let item of points[group]) { + if (item.name === null) { + item.name = find_label(item.x, item.y, 72) } } - - 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 +for (let group in boxes) { + for (let item of boxes[group]) { + if (item.name === null) { + item.name = find_label(item.x+item.w/2, item.y+item.w/2, 72) } } - - 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 group in edges) { + for (let item of edges[group]) { + item.name1 = find_label(item.x1, item.y1, 72) + item.name2 = find_label(item.x2, item.y2, 72) } } -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") -*/ +fs.writeFileSync("tools/layout.json", JSON.stringify({boxes,points,edges,labels}, null, 4)) diff --git a/tools/process-layout.js b/tools/process-layout.js new file mode 100644 index 0000000..6de0844 --- /dev/null +++ b/tools/process-layout.js @@ -0,0 +1,164 @@ +"use strict" + +const fs = require("fs") + +let layout = JSON.parse(fs.readFileSync("tools/layout.json", "utf-8")) + +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 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 +} + +const SEAS = [ "Sea1", "Sea2", "Sea3", "Sea4", "Sea5", "Sea6", "Sea7" ] +const COLONIES = [ "Canada", "NH", "NY", "MA", "CT", "RI", "PA", "NJ", "MD", "DE", "VA", "NC", "SC", "GA", ] + +let seas = SEAS.map(x => []) +let colonies = COLONIES.map(x => []) + +let spaces = [] +let space_index = {} + +function add_space(type, name, x, y) { + let id = spaces.length + spaces.push({ + name, + type, + adjacent: [], + path: [], + wilderness: [], + port: -1, + colony: -1, + x: Math.round(x), + y: Math.round(y), + }) +} + +function add_edge(type, a, b) { + let ax = space_index[a] + let bx = space_index[b] + set_add(spaces[ax][type], bx) + set_add(spaces[bx][type], ax) + set_add(spaces[ax].adjacent, bx) + set_add(spaces[bx].adjacent, ax) +} + +function add_oneway(type, a, b, list2, set2) { + let ax = space_index[a] + let bx = space_index[b] + if (ax !== undefined) { + let k = list2.indexOf(b) + spaces[ax][type] = k + set_add(set2[k], ax) + } + if (bx !== undefined) { + let k = list2.indexOf(a) + spaces[bx][type] = k + set_add(set2[k], bx) + } +} + +for (let item of layout.points.fortified_port) + add_space("fortified_port", item.name, item.x, item.y) +for (let item of layout.points.winter_quarters) + add_space("winter_quarters", item.name, item.x, item.y) +for (let item of layout.points.regular) + add_space("regular", item.name, item.x, item.y) +for (let item of layout.points.box) + add_space("box", item.name, item.x, item.y) + +const TYPE_SORT = [ "fortified_port", "winter_quarters", "regular", "box" ] + +spaces.sort((a,b) => { + let at = TYPE_SORT.indexOf(a.type) + let bt = TYPE_SORT.indexOf(b.type) + if (at < bt) return -1 + if (at > bt) return 1 + if (a.name < b.name) return -1 + if (a.name > b.name) return 1 + return b.y - a.y +}) + +for (let i = 0; i < spaces.length; ++i) + space_index[spaces[i].name] = i + +for (let item of layout.edges.sea) + add_oneway("port", item.name1, item.name2, SEAS, seas) +for (let item of layout.edges.colony) + add_oneway("colony", item.name1, item.name2, COLONIES, colonies) + +for (let item of layout.edges.path) + add_edge("path", item.name1, item.name2) +for (let item of layout.edges.wilderness) + add_edge("wilderness", item.name1, item.name2) + + +function map_point(group, name) { + let item = layout.points[group].find(item => item.name === name) + return [ item.x, item.y ].map(Math.round) +} + +function map_box(group, name) { + let item = layout.boxes[group].find(item => item.name === name) + return [ item.x, item.y, item.w, item.h ].map(Math.round) +} + +function map_point_list(group, names) { + return names.map(n => map_point(group, n)) +} + +function map_box_list(group, names) { + return names.map(n => map_box(group, n)) +} + +function map_box_dict(list) { + let out = {} + for (let item of list) + out[item.name] = [ item.x, item.y, item.w, item.h ].map(Math.round) + return out +} + +function map_point_dict(list) { + let out = {} + for (let item of list) + out[item.name] = [ item.x, item.y ].map(Math.round) + return out +} + +let boxes = { + sea: map_box_list("sea", SEAS), + colony: map_point_list("colony", COLONIES), + french_alliance_track: map_point_dict(layout.points["French Alliance Track"]), + turn: map_point_dict(layout.points["Game Turn"]), + card_box: map_point_dict(layout.points["Card Boxes"]), + box: map_box_dict(layout.boxes.box), +} + +let data = { layout: boxes, spaces, space_index, colonies, seas } + +fs.writeFileSync("tools/data.json", JSON.stringify(data)) diff --git a/tools/rotate_year.sh b/tools/rotate_year.sh new file mode 100644 index 0000000..96a6c2b --- /dev/null +++ b/tools/rotate_year.sh @@ -0,0 +1,8 @@ +for DIR in cards75 cards100 cards150 cards200 +do + convert -rotate 90 $DIR/card_7.png $DIR/card_7_rot.png + convert -rotate 90 $DIR/card_8.png $DIR/card_8_rot.png + convert -rotate 90 $DIR/card_9.png $DIR/card_9_rot.png + convert -rotate 90 $DIR/card_10.png $DIR/card_10_rot.png + convert -rotate 90 $DIR/card_11.png $DIR/card_11_rot.png +done |