summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-02-26 11:53:38 +0100
committerTor Andersson <tor@ccxvii.net>2023-05-03 18:48:15 +0200
commitbbb9a7bd3686f5a16e661a2a3e8e8c94f8e2bfe2 (patch)
tree94682a8aabc79ca5e816be64f3d24bd35c81258a
parentf40f5ba5e04dfa22cf7565330f4da0fbafc68436 (diff)
downloadandean-abyss-bbb9a7bd3686f5a16e661a2a3e8e8c94f8e2bfe2.tar.gz
piece lists
-rw-r--r--data.js1467
-rw-r--r--play.html14
-rw-r--r--play.js359
-rw-r--r--rules.js587
-rw-r--r--tools/gendata.js67
5 files changed, 595 insertions, 1899 deletions
diff --git a/data.js b/data.js
index 76bce08..cf3eef4 100644
--- a/data.js
+++ b/data.js
@@ -1,1467 +1,2 @@
-const data = {
- "first_pop": 1,
- "first_city": 0,
- "last_city": 10,
- "first_dept": 11,
- "last_pop": 22,
- "last_dept": 26,
- "first_foreign": 27,
- "last_foreign": 31,
- "first_loc": 32,
- "last_loc": 49,
- "coastal_spaces": [
- 11,
- 12,
- 13,
- 17
- ],
- "cards": [
- null,
- {
- "number": 1,
- "name": "1st Division",
- "order": [
- "Government",
- "FARC",
- "AUC",
- "Cartels"
- ]
- },
- {
- "number": 2,
- "name": "Ospina & Mora",
- "order": [
- "Government",
- "FARC",
- "AUC",
- "Cartels"
- ]
- },
- {
- "number": 3,
- "name": "Tapias",
- "order": [
- "Government",
- "FARC",
- "AUC",
- "Cartels"
- ]
- },
- {
- "number": 4,
- "name": "Caño Limón - Coveñas",
- "order": [
- "Government",
- "FARC",
- "Cartels",
- "AUC"
- ]
- },
- {
- "number": 5,
- "name": "Occidental & Ecopetrol",
- "order": [
- "Government",
- "FARC",
- "Cartels",
- "AUC"
- ]
- },
- {
- "number": 6,
- "name": "Oil Spill",
- "order": [
- "Government",
- "FARC",
- "Cartels",
- "AUC"
- ]
- },
- {
- "number": 7,
- "name": "7th Special Forces",
- "order": [
- "Government",
- "AUC",
- "FARC",
- "Cartels"
- ]
- },
- {
- "number": 8,
- "name": "Fuerza Aérea Colombiana",
- "order": [
- "Government",
- "AUC",
- "FARC",
- "Cartels"
- ]
- },
- {
- "number": 9,
- "name": "High Mountain Battalions",
- "order": [
- "Government",
- "AUC",
- "FARC",
- "Cartels"
- ]
- },
- {
- "number": 10,
- "name": "Blackhawks",
- "order": [
- "Government",
- "AUC",
- "Cartels",
- "FARC"
- ]
- },
- {
- "number": 11,
- "name": "National Defense & Security Council",
- "order": [
- "Government",
- "AUC",
- "Cartels",
- "FARC"
- ]
- },
- {
- "number": 12,
- "name": "Plan Colombia",
- "order": [
- "Government",
- "AUC",
- "Cartels",
- "FARC"
- ]
- },
- {
- "number": 13,
- "name": "Plan Meteoro",
- "order": [
- "Government",
- "Cartels",
- "FARC",
- "AUC"
- ]
- },
- {
- "number": 14,
- "name": "Tres Esquinas",
- "order": [
- "Government",
- "Cartels",
- "FARC",
- "AUC"
- ]
- },
- {
- "number": 15,
- "name": "War Tax",
- "order": [
- "Government",
- "Cartels",
- "FARC",
- "AUC"
- ]
- },
- {
- "number": 16,
- "name": "Coffee Prices",
- "order": [
- "Government",
- "Cartels",
- "AUC",
- "FARC"
- ]
- },
- {
- "number": 17,
- "name": "Madrid Donors",
- "order": [
- "Government",
- "Cartels",
- "AUC",
- "FARC"
- ]
- },
- {
- "number": 18,
- "name": "NSPD-18",
- "order": [
- "Government",
- "Cartels",
- "AUC",
- "FARC"
- ]
- },
- {
- "number": 19,
- "name": "General Offensive",
- "order": [
- "FARC",
- "Government",
- "AUC",
- "Cartels"
- ]
- },
- {
- "number": 20,
- "name": "Mono Jojoy",
- "order": [
- "FARC",
- "Government",
- "AUC",
- "Cartels"
- ]
- },
- {
- "number": 21,
- "name": "Raúl Reyes",
- "order": [
- "FARC",
- "Government",
- "AUC",
- "Cartels"
- ]
- },
- {
- "number": 22,
- "name": "Alfonso Cano",
- "order": [
- "FARC",
- "Government",
- "Cartels",
- "AUC"
- ]
- },
- {
- "number": 23,
- "name": "DoD Contractors",
- "order": [
- "FARC",
- "Government",
- "Cartels",
- "AUC"
- ]
- },
- {
- "number": 24,
- "name": "Operación Jaque",
- "order": [
- "FARC",
- "Government",
- "Cartels",
- "AUC"
- ]
- },
- {
- "number": 25,
- "name": "Ejército de Liberación Nacional",
- "order": [
- "FARC",
- "AUC",
- "Government",
- "Cartels"
- ]
- },
- {
- "number": 26,
- "name": "Gramaje",
- "order": [
- "FARC",
- "AUC",
- "Government",
- "Cartels"
- ]
- },
- {
- "number": 27,
- "name": "Misil Antiaéreo",
- "order": [
- "FARC",
- "AUC",
- "Government",
- "Cartels"
- ]
- },
- {
- "number": 28,
- "name": "Hugo Chávez",
- "order": [
- "FARC",
- "AUC",
- "Cartels",
- "Government"
- ]
- },
- {
- "number": 29,
- "name": "Kill Zone",
- "order": [
- "FARC",
- "AUC",
- "Cartels",
- "Government"
- ]
- },
- {
- "number": 30,
- "name": "Peace Commission",
- "order": [
- "FARC",
- "AUC",
- "Cartels",
- "Government"
- ]
- },
- {
- "number": 31,
- "name": "Betancourt",
- "order": [
- "FARC",
- "Cartels",
- "Government",
- "AUC"
- ]
- },
- {
- "number": 32,
- "name": "Secuestrados",
- "order": [
- "FARC",
- "Cartels",
- "Government",
- "AUC"
- ]
- },
- {
- "number": 33,
- "name": "Sucumbíos",
- "order": [
- "FARC",
- "Cartels",
- "Government",
- "AUC"
- ]
- },
- {
- "number": 34,
- "name": "Airdropped AKs",
- "order": [
- "FARC",
- "Cartels",
- "AUC",
- "Government"
- ]
- },
- {
- "number": 35,
- "name": "Crop Substitution",
- "order": [
- "FARC",
- "Cartels",
- "AUC",
- "Government"
- ]
- },
- {
- "number": 36,
- "name": "Zona de Convivencia",
- "order": [
- "FARC",
- "Cartels",
- "AUC",
- "Government"
- ]
- },
- {
- "number": 37,
- "name": "Former Military",
- "order": [
- "AUC",
- "Government",
- "FARC",
- "Cartels"
- ]
- },
- {
- "number": 38,
- "name": "National Coordination Center",
- "order": [
- "AUC",
- "Government",
- "FARC",
- "Cartels"
- ]
- },
- {
- "number": 39,
- "name": "Soldados Campesinos",
- "order": [
- "AUC",
- "Government",
- "FARC",
- "Cartels"
- ]
- },
- {
- "number": 40,
- "name": "Demobilization",
- "order": [
- "AUC",
- "Government",
- "Cartels",
- "FARC"
- ]
- },
- {
- "number": 41,
- "name": "Mancuso",
- "order": [
- "AUC",
- "Government",
- "Cartels",
- "FARC"
- ]
- },
- {
- "number": 42,
- "name": "Senado & Cámara",
- "order": [
- "AUC",
- "Government",
- "Cartels",
- "FARC"
- ]
- },
- {
- "number": 43,
- "name": "Calima Front",
- "order": [
- "AUC",
- "FARC",
- "Government",
- "Cartels"
- ]
- },
- {
- "number": 44,
- "name": "Colombia Nueva",
- "order": [
- "AUC",
- "FARC",
- "Government",
- "Cartels"
- ]
- },
- {
- "number": 45,
- "name": "Los Derechos Humanos",
- "order": [
- "AUC",
- "FARC",
- "Government",
- "Cartels"
- ]
- },
- {
- "number": 46,
- "name": "Limpieza",
- "order": [
- "AUC",
- "FARC",
- "Cartels",
- "Government"
- ]
- },
- {
- "number": 47,
- "name": "Pinto & del Rosario",
- "order": [
- "AUC",
- "FARC",
- "Cartels",
- "Government"
- ]
- },
- {
- "number": 48,
- "name": "Unión Sindical Obrera",
- "order": [
- "AUC",
- "FARC",
- "Cartels",
- "Government"
- ]
- },
- {
- "number": 49,
- "name": "Bloques",
- "order": [
- "AUC",
- "Cartels",
- "Government",
- "FARC"
- ]
- },
- {
- "number": 50,
- "name": "Carabineros",
- "order": [
- "AUC",
- "Cartels",
- "Government",
- "FARC"
- ]
- },
- {
- "number": 51,
- "name": "Pipeline Repairs",
- "order": [
- "AUC",
- "Cartels",
- "Government",
- "FARC"
- ]
- },
- {
- "number": 52,
- "name": "Castaño",
- "order": [
- "AUC",
- "Cartels",
- "FARC",
- "Government"
- ]
- },
- {
- "number": 53,
- "name": "Criminal Air Force",
- "order": [
- "AUC",
- "Cartels",
- "FARC",
- "Government"
- ]
- },
- {
- "number": 54,
- "name": "Deserters & Defectors",
- "order": [
- "AUC",
- "Cartels",
- "FARC",
- "Government"
- ]
- },
- {
- "number": 55,
- "name": "DEA Agents",
- "order": [
- "Cartels",
- "Government",
- "FARC",
- "AUC"
- ]
- },
- {
- "number": 56,
- "name": "Drogas La Rebaja",
- "order": [
- "Cartels",
- "Government",
- "FARC",
- "AUC"
- ]
- },
- {
- "number": 57,
- "name": "Op Millennium",
- "order": [
- "Cartels",
- "Government",
- "FARC",
- "AUC"
- ]
- },
- {
- "number": 58,
- "name": "General Serrano",
- "order": [
- "Cartels",
- "Government",
- "AUC",
- "FARC"
- ]
- },
- {
- "number": 59,
- "name": "Salcedo",
- "order": [
- "Cartels",
- "Government",
- "AUC",
- "FARC"
- ]
- },
- {
- "number": 60,
- "name": "The Chess Player",
- "order": [
- "Cartels",
- "Government",
- "AUC",
- "FARC"
- ]
- },
- {
- "number": 61,
- "name": "Air Bridge",
- "order": [
- "Cartels",
- "FARC",
- "Government",
- "AUC"
- ]
- },
- {
- "number": 62,
- "name": "Amazonía",
- "order": [
- "Cartels",
- "FARC",
- "Government",
- "AUC"
- ]
- },
- {
- "number": 63,
- "name": "Narco-War",
- "order": [
- "Cartels",
- "FARC",
- "Government",
- "AUC"
- ]
- },
- {
- "number": 64,
- "name": "Cocaine Labs",
- "order": [
- "Cartels",
- "FARC",
- "AUC",
- "Government"
- ]
- },
- {
- "number": 65,
- "name": "Poppies",
- "order": [
- "Cartels",
- "FARC",
- "AUC",
- "Government"
- ]
- },
- {
- "number": 66,
- "name": "Tingo María",
- "order": [
- "Cartels",
- "FARC",
- "AUC",
- "Government"
- ]
- },
- {
- "number": 67,
- "name": "Mexican Traffickers",
- "order": [
- "Cartels",
- "AUC",
- "Government",
- "FARC"
- ]
- },
- {
- "number": 68,
- "name": "Narco-Subs",
- "order": [
- "Cartels",
- "AUC",
- "Government",
- "FARC"
- ]
- },
- {
- "number": 69,
- "name": "Riverines & Fast Boats",
- "order": [
- "Cartels",
- "AUC",
- "Government",
- "FARC"
- ]
- },
- {
- "number": 70,
- "name": "Ayahuasca Tourism",
- "order": [
- "Cartels",
- "AUC",
- "FARC",
- "Government"
- ]
- },
- {
- "number": 71,
- "name": "Darién",
- "order": [
- "Cartels",
- "AUC",
- "FARC",
- "Government"
- ]
- },
- {
- "number": 72,
- "name": "Sicarios",
- "order": [
- "Cartels",
- "AUC",
- "FARC",
- "Government"
- ]
- },
- {
- "number": 73,
- "name": "Propaganda!",
- "order": null
- },
- {
- "number": 74,
- "name": "Propaganda!",
- "order": null
- },
- {
- "number": 75,
- "name": "Propaganda!",
- "order": null
- },
- {
- "number": 76,
- "name": "Propaganda!",
- "order": null
- }
- ],
- "spaces": [
- {
- "type": "city",
- "id": "Bogota",
- "name": "Bogotá",
- "pop": 8,
- "adjacent": [
- 35,
- 42,
- 43,
- 45,
- 19,
- 22,
- 14,
- 20
- ]
- },
- {
- "type": "city",
- "id": "Cali",
- "name": "Cali",
- "pop": 3,
- "adjacent": [
- 12,
- 13,
- 20,
- 33,
- 37,
- 41
- ]
- },
- {
- "type": "city",
- "id": "Medellin",
- "name": "Medellín",
- "pop": 3,
- "adjacent": [
- 12,
- 18,
- 39,
- 40
- ]
- },
- {
- "type": "city",
- "id": "Bucaramanga",
- "name": "Bucaramanga",
- "pop": 2,
- "adjacent": [
- 18,
- 19,
- 42,
- 47
- ]
- },
- {
- "type": "city",
- "id": "Ibague",
- "name": "Ibagué",
- "pop": 2,
- "adjacent": [
- 12,
- 18,
- 20,
- 40,
- 41,
- 42
- ]
- },
- {
- "type": "city",
- "id": "Santa Marta",
- "name": "Santa Marta",
- "pop": 2,
- "adjacent": [
- 11,
- 17,
- 32,
- 46
- ]
- },
- {
- "type": "city",
- "id": "Cartagena",
- "name": "Cartagena",
- "pop": 1,
- "adjacent": [
- 11,
- 32,
- 38
- ]
- },
- {
- "type": "city",
- "id": "Cucuta",
- "name": "Cúcuta",
- "pop": 1,
- "adjacent": [
- 19,
- 31,
- 44,
- 49
- ]
- },
- {
- "type": "city",
- "id": "Neiva",
- "name": "Neiva",
- "pop": 1,
- "adjacent": [
- 14,
- 16,
- 20,
- 34,
- 43
- ]
- },
- {
- "type": "city",
- "id": "Pasto",
- "name": "Pasto",
- "pop": 1,
- "adjacent": [
- 13,
- 16,
- 20,
- 28,
- 33,
- 34,
- 36
- ]
- },
- {
- "type": "city",
- "id": "Sincelejo",
- "name": "Sincelejo",
- "pop": 1,
- "adjacent": [
- 11,
- 12,
- 18,
- 38,
- 39,
- 48
- ]
- },
- {
- "type": "forest",
- "id": "Atlantico",
- "name": "Atlántico",
- "pop": 1,
- "adjacent": [
- 5,
- 6,
- 10,
- 17,
- 18,
- 19,
- 32,
- 38,
- 46,
- 47,
- 48,
- 49
- ]
- },
- {
- "type": "forest",
- "id": "Choco",
- "name": "Chocó",
- "pop": 1,
- "adjacent": [
- 1,
- 2,
- 4,
- 10,
- 13,
- 18,
- 20,
- 29,
- 37,
- 39,
- 40,
- 41
- ]
- },
- {
- "type": "forest",
- "id": "Narino",
- "name": "Nariño",
- "pop": 1,
- "adjacent": [
- 1,
- 9,
- 12,
- 20,
- 28,
- 33,
- 36,
- 37
- ]
- },
- {
- "type": "forest",
- "id": "Meta West",
- "name": "Meta West",
- "pop": 1,
- "adjacent": [
- 0,
- 8,
- 15,
- 16,
- 20,
- 22,
- 35,
- 43
- ]
- },
- {
- "type": "forest",
- "id": "Guaviare",
- "name": "Guaviare",
- "pop": 1,
- "adjacent": [
- 14,
- 16,
- 22,
- 23,
- 24,
- 25,
- 35
- ]
- },
- {
- "type": "forest",
- "id": "Putumayo",
- "name": "Putumayo",
- "pop": 1,
- "adjacent": [
- 8,
- 9,
- 14,
- 15,
- 20,
- 25,
- 26,
- 28,
- 30,
- 34
- ]
- },
- {
- "type": "mountain",
- "id": "Cesar",
- "name": "Cesar",
- "pop": 1,
- "adjacent": [
- 5,
- 11,
- 18,
- 19,
- 31,
- 46,
- 47,
- 48,
- 49
- ]
- },
- {
- "type": "mountain",
- "id": "Antioquia",
- "name": "Antioquia",
- "pop": 2,
- "adjacent": [
- 2,
- 3,
- 4,
- 10,
- 11,
- 12,
- 17,
- 19,
- 20,
- 39,
- 40,
- 42,
- 46,
- 47,
- 48,
- 49
- ]
- },
- {
- "type": "mountain",
- "id": "Santander",
- "name": "Santander",
- "pop": 2,
- "adjacent": [
- 0,
- 3,
- 7,
- 11,
- 17,
- 18,
- 20,
- 21,
- 22,
- 31,
- 45,
- 46,
- 47,
- 48,
- 49
- ]
- },
- {
- "type": "mountain",
- "id": "Huila",
- "name": "Huila",
- "pop": 2,
- "adjacent": [
- 0,
- 1,
- 4,
- 8,
- 9,
- 12,
- 13,
- 14,
- 16,
- 18,
- 19,
- 33,
- 34,
- 41,
- 42,
- 43
- ]
- },
- {
- "type": "grassland",
- "id": "Arauca",
- "name": "Arauca",
- "pop": 1,
- "adjacent": [
- 19,
- 22,
- 23,
- 31,
- 44,
- 45
- ]
- },
- {
- "type": "grassland",
- "id": "Meta East",
- "name": "Meta East",
- "pop": 1,
- "adjacent": [
- 0,
- 14,
- 15,
- 19,
- 21,
- 23,
- 35,
- 45
- ]
- },
- {
- "type": "grassland",
- "id": "Vichada",
- "name": "Vichada",
- "pop": 0,
- "adjacent": [
- 15,
- 21,
- 22,
- 24,
- 31
- ]
- },
- {
- "type": "forest",
- "id": "Guainia",
- "name": "Guainía",
- "pop": 0,
- "adjacent": [
- 15,
- 23,
- 25,
- 27,
- 31
- ]
- },
- {
- "type": "forest",
- "id": "Vaupes",
- "name": "Vaupés",
- "pop": 0,
- "adjacent": [
- 15,
- 16,
- 24,
- 26,
- 27
- ]
- },
- {
- "type": "forest",
- "id": "Amazonas",
- "name": "Amazonas",
- "pop": 0,
- "adjacent": [
- 16,
- 25,
- 27,
- 30
- ]
- },
- {
- "type": "foreign",
- "id": "Brasil",
- "name": "Brasil",
- "pop": 0,
- "adjacent": [
- 24,
- 25,
- 26
- ]
- },
- {
- "type": "foreign",
- "id": "Ecuador",
- "name": "Ecuador",
- "pop": 0,
- "adjacent": [
- 9,
- 13,
- 16,
- 36
- ]
- },
- {
- "type": "foreign",
- "id": "Panama",
- "name": "Panamá",
- "pop": 0,
- "adjacent": [
- 12
- ]
- },
- {
- "type": "foreign",
- "id": "Peru",
- "name": "Perú",
- "pop": 0,
- "adjacent": [
- 16,
- 26
- ]
- },
- {
- "type": "foreign",
- "id": "Venezuela",
- "name": "Venezuela",
- "pop": 0,
- "adjacent": [
- 7,
- 17,
- 19,
- 21,
- 23,
- 24,
- 44,
- 49
- ]
- },
- {
- "type": "road",
- "name": "Santa Marta / Cartagena",
- "id": "Santa Marta / Cartagena",
- "econ": 1,
- "adjacent": [
- 5,
- 6,
- 11
- ]
- },
- {
- "type": "road",
- "name": "Cali / Pasto",
- "id": "Cali / Pasto",
- "econ": 1,
- "adjacent": [
- 1,
- 9,
- 13,
- 20
- ]
- },
- {
- "type": "road",
- "name": "Neiva / Pasto",
- "id": "Neiva / Pasto",
- "econ": 1,
- "adjacent": [
- 8,
- 9,
- 16,
- 20
- ]
- },
- {
- "type": "road",
- "name": "Bogotá / San José",
- "id": "Bogota / San Jose",
- "econ": 1,
- "adjacent": [
- 14,
- 15,
- 22
- ]
- },
- {
- "type": "road",
- "name": "Pasto / Tumaco",
- "id": "Pasto / Tumaco",
- "econ": 1,
- "adjacent": [
- 9,
- 13,
- 28
- ]
- },
- {
- "type": "pipeline",
- "name": "Cali / Buenaventura",
- "id": "Cali / Buenaventura",
- "econ": 1,
- "adjacent": [
- 1,
- 12,
- 13
- ]
- },
- {
- "type": "pipeline",
- "name": "Cartagena / Sincelejo",
- "id": "Cartagena / Sincelejo",
- "econ": 1,
- "adjacent": [
- 6,
- 10,
- 11
- ]
- },
- {
- "type": "pipeline",
- "name": "Sincelejo / Medellín",
- "id": "Sincelejo / Medellin",
- "econ": 2,
- "adjacent": [
- 2,
- 10,
- 12,
- 18
- ]
- },
- {
- "type": "pipeline",
- "name": "Medellín / Ibagué",
- "id": "Medellin / Ibague",
- "econ": 1,
- "adjacent": [
- 2,
- 4,
- 12,
- 18
- ]
- },
- {
- "type": "pipeline",
- "name": "Ibagué / Cali",
- "id": "Ibague / Cali",
- "econ": 1,
- "adjacent": [
- 1,
- 4,
- 12,
- 20
- ]
- },
- {
- "type": "pipeline",
- "name": "Bucaramanga / Ibagué / Bogotá",
- "id": "Bucaramanga / Ibague / Bogota",
- "econ": 2,
- "adjacent": [
- 3,
- 4,
- 18,
- 20
- ]
- },
- {
- "type": "pipeline",
- "name": "Bogotá / Neiva",
- "id": "Bogota / Neiva",
- "econ": 2,
- "adjacent": [
- 8,
- 14,
- 20
- ]
- },
- {
- "type": "pipeline",
- "name": "Cúcuta / Arauca",
- "id": "Cucuta / Arauca",
- "econ": 3,
- "adjacent": [
- 7,
- 21,
- 21,
- 31
- ]
- },
- {
- "type": "pipeline",
- "name": "Bogotá / Yopal",
- "id": "Bogota / Yopal",
- "econ": 2,
- "adjacent": [
- 19,
- 21,
- 22
- ]
- },
- {
- "type": "pipeline",
- "name": "Santa Marta / Ayacucho",
- "id": "Santa Marta / Ayacucho",
- "econ": 2,
- "adjacent": [
- 5,
- 11,
- 17,
- 18,
- 19,
- 47,
- 48,
- 49
- ]
- },
- {
- "type": "pipeline",
- "name": "Bucaramanga / Ayacucho",
- "id": "Bucaramanga / Ayacucho",
- "econ": 2,
- "adjacent": [
- 3,
- 11,
- 17,
- 18,
- 19,
- 46,
- 48,
- 49
- ]
- },
- {
- "type": "pipeline",
- "name": "Sincelejo / Ayacucho",
- "id": "Sincelejo / Ayacucho",
- "econ": 3,
- "adjacent": [
- 10,
- 11,
- 17,
- 18,
- 19,
- 46,
- 47,
- 49
- ]
- },
- {
- "type": "pipeline",
- "name": "Cúcuta / Ayacucho",
- "id": "Cucuta / Ayacucho",
- "econ": 3,
- "adjacent": [
- 7,
- 11,
- 17,
- 18,
- 19,
- 31,
- 46,
- 47,
- 48
- ]
- }
- ]
-}
+const data = {"first_pop":1,"first_city":0,"last_city":10,"first_dept":11,"last_pop":22,"last_dept":26,"first_foreign":27,"last_foreign":31,"first_loc":32,"last_loc":49,"coastal_spaces":[11,12,13,17],"card_name":[null,"1st Division","Ospina & Mora","Tapias","Caño Limón - Coveñas","Occidental & Ecopetrol","Oil Spill","7th Special Forces","Fuerza Aérea Colombiana","High Mountain Battalions","Blackhawks","National Defense & Security Council","Plan Colombia","Plan Meteoro","Tres Esquinas","War Tax","Coffee Prices","Madrid Donors","NSPD-18","General Offensive","Mono Jojoy","Raúl Reyes","Alfonso Cano","DoD Contractors","Operación Jaque","Ejército de Liberación Nacional","Gramaje","Misil Antiaéreo","Hugo Chávez","Kill Zone","Peace Commission","Betancourt","Secuestrados","Sucumbíos","Airdropped AKs","Crop Substitution","Zona de Convivencia","Former Military","National Coordination Center","Soldados Campesinos","Demobilization","Mancuso","Senado & Cámara","Calima Front","Colombia Nueva","Los Derechos Humanos","Limpieza","Pinto & del Rosario","Unión Sindical Obrera","Bloques","Carabineros","Pipeline Repairs","Castaño","Criminal Air Force","Deserters & Defectors","DEA Agents","Drogas La Rebaja","Op Millennium","General Serrano","Salcedo","The Chess Player","Air Bridge","Amazonía","Narco-War","Cocaine Labs","Poppies","Tingo María","Mexican Traffickers","Narco-Subs","Riverines & Fast Boats","Ayahuasca Tourism","Darién","Sicarios","Propaganda!","Propaganda!","Propaganda!","Propaganda!"],"card_order":[null,[0,1,2,3],[0,1,2,3],[0,1,2,3],[0,1,3,2],[0,1,3,2],[0,1,3,2],[0,2,1,3],[0,2,1,3],[0,2,1,3],[0,2,3,1],[0,2,3,1],[0,2,3,1],[0,3,1,2],[0,3,1,2],[0,3,1,2],[0,3,2,1],[0,3,2,1],[0,3,2,1],[1,0,2,3],[1,0,2,3],[1,0,2,3],[1,0,3,2],[1,0,3,2],[1,0,3,2],[1,2,0,3],[1,2,0,3],[1,2,0,3],[1,2,3,0],[1,2,3,0],[1,2,3,0],[1,3,0,2],[1,3,0,2],[1,3,0,2],[1,3,2,0],[1,3,2,0],[1,3,2,0],[2,0,1,3],[2,0,1,3],[2,0,1,3],[2,0,3,1],[2,0,3,1],[2,0,3,1],[2,1,0,3],[2,1,0,3],[2,1,0,3],[2,1,3,0],[2,1,3,0],[2,1,3,0],[2,3,0,1],[2,3,0,1],[2,3,0,1],[2,3,1,0],[2,3,1,0],[2,3,1,0],[3,0,1,2],[3,0,1,2],[3,0,1,2],[3,0,2,1],[3,0,2,1],[3,0,2,1],[3,1,0,2],[3,1,0,2],[3,1,0,2],[3,1,2,0],[3,1,2,0],[3,1,2,0],[3,2,0,1],[3,2,0,1],[3,2,0,1],[3,2,1,0],[3,2,1,0],[3,2,1,0],null,null,null,null],"space_name":["Bogotá","Cali","Medellín","Bucaramanga","Ibagué","Santa Marta","Cartagena","Cúcuta","Neiva","Pasto","Sincelejo","Atlántico","Chocó","Nariño","Meta West","Guaviare","Putumayo","Cesar","Antioquia","Santander","Huila","Arauca","Meta East","Vichada","Guainía","Vaupés","Amazonas","Brasil","Ecuador","Panamá","Perú","Venezuela","Santa Marta / Cartagena","Cali / Pasto","Neiva / Pasto","Bogotá / San José","Pasto / Tumaco","Cali / Buenaventura","Cartagena / Sincelejo","Sincelejo / Medellín","Medellín / Ibagué","Ibagué / Cali","Bucaramanga / Ibagué / Bogotá","Bogotá / Neiva","Cúcuta / Arauca","Bogotá / Yopal","Santa Marta / Ayacucho","Bucaramanga / Ayacucho","Sincelejo / Ayacucho","Cúcuta / Ayacucho"],"spaces":[{"type":"city","id":"Bogota","pop":8,"adjacent":[35,42,43,45,19,22,14,20]},{"type":"city","id":"Cali","pop":3,"adjacent":[12,13,20,33,37,41]},{"type":"city","id":"Medellin","pop":3,"adjacent":[12,18,39,40]},{"type":"city","id":"Bucaramanga","pop":2,"adjacent":[18,19,42,47]},{"type":"city","id":"Ibague","pop":2,"adjacent":[12,18,20,40,41,42]},{"type":"city","id":"Santa Marta","pop":2,"adjacent":[11,17,32,46]},{"type":"city","id":"Cartagena","pop":1,"adjacent":[11,32,38]},{"type":"city","id":"Cucuta","pop":1,"adjacent":[19,31,44,49]},{"type":"city","id":"Neiva","pop":1,"adjacent":[14,16,20,34,43]},{"type":"city","id":"Pasto","pop":1,"adjacent":[13,16,20,28,33,34,36]},{"type":"city","id":"Sincelejo","pop":1,"adjacent":[11,12,18,38,39,48]},{"type":"forest","id":"Atlantico","pop":1,"adjacent":[5,6,10,17,18,19,32,38,46,47,48,49]},{"type":"forest","id":"Choco","pop":1,"adjacent":[1,2,4,10,13,18,20,29,37,39,40,41]},{"type":"forest","id":"Narino","pop":1,"adjacent":[1,9,12,20,28,33,36,37]},{"type":"forest","id":"Meta West","pop":1,"adjacent":[0,8,15,16,20,22,35,43]},{"type":"forest","id":"Guaviare","pop":1,"adjacent":[14,16,22,23,24,25,35]},{"type":"forest","id":"Putumayo","pop":1,"adjacent":[8,9,14,15,20,25,26,28,30,34]},{"type":"mountain","id":"Cesar","pop":1,"adjacent":[5,11,18,19,31,46,47,48,49]},{"type":"mountain","id":"Antioquia","pop":2,"adjacent":[2,3,4,10,11,12,17,19,20,39,40,42,46,47,48,49]},{"type":"mountain","id":"Santander","pop":2,"adjacent":[0,3,7,11,17,18,20,21,22,31,45,46,47,48,49]},{"type":"mountain","id":"Huila","pop":2,"adjacent":[0,1,4,8,9,12,13,14,16,18,19,33,34,41,42,43]},{"type":"grassland","id":"Arauca","pop":1,"adjacent":[19,22,23,31,44,45]},{"type":"grassland","id":"Meta East","pop":1,"adjacent":[0,14,15,19,21,23,35,45]},{"type":"grassland","id":"Vichada","pop":0,"adjacent":[15,21,22,24,31]},{"type":"forest","id":"Guainia","pop":0,"adjacent":[15,23,25,27,31]},{"type":"forest","id":"Vaupes","pop":0,"adjacent":[15,16,24,26,27]},{"type":"forest","id":"Amazonas","pop":0,"adjacent":[16,25,27,30]},{"type":"foreign","id":"Brasil","pop":0,"adjacent":[24,25,26]},{"type":"foreign","id":"Ecuador","pop":0,"adjacent":[9,13,16,36]},{"type":"foreign","id":"Panama","pop":0,"adjacent":[12]},{"type":"foreign","id":"Peru","pop":0,"adjacent":[16,26]},{"type":"foreign","id":"Venezuela","pop":0,"adjacent":[7,17,19,21,23,24,44,49]},{"type":"road","name":"Santa Marta / Cartagena","id":"Santa Marta / Cartagena","econ":1,"adjacent":[5,6,11]},{"type":"road","name":"Cali / Pasto","id":"Cali / Pasto","econ":1,"adjacent":[1,9,13,20]},{"type":"road","name":"Neiva / Pasto","id":"Neiva / Pasto","econ":1,"adjacent":[8,9,16,20]},{"type":"road","name":"Bogotá / San José","id":"Bogota / San Jose","econ":1,"adjacent":[14,15,22]},{"type":"road","name":"Pasto / Tumaco","id":"Pasto / Tumaco","econ":1,"adjacent":[9,13,28]},{"type":"pipeline","name":"Cali / Buenaventura","id":"Cali / Buenaventura","econ":1,"adjacent":[1,12,13]},{"type":"pipeline","name":"Cartagena / Sincelejo","id":"Cartagena / Sincelejo","econ":1,"adjacent":[6,10,11]},{"type":"pipeline","name":"Sincelejo / Medellín","id":"Sincelejo / Medellin","econ":2,"adjacent":[2,10,12,18]},{"type":"pipeline","name":"Medellín / Ibagué","id":"Medellin / Ibague","econ":1,"adjacent":[2,4,12,18]},{"type":"pipeline","name":"Ibagué / Cali","id":"Ibague / Cali","econ":1,"adjacent":[1,4,12,20]},{"type":"pipeline","name":"Bucaramanga / Ibagué / Bogotá","id":"Bucaramanga / Ibague / Bogota","econ":2,"adjacent":[3,4,18,20]},{"type":"pipeline","name":"Bogotá / Neiva","id":"Bogota / Neiva","econ":2,"adjacent":[8,14,20]},{"type":"pipeline","name":"Cúcuta / Arauca","id":"Cucuta / Arauca","econ":3,"adjacent":[7,21,21,31]},{"type":"pipeline","name":"Bogotá / Yopal","id":"Bogota / Yopal","econ":2,"adjacent":[19,21,22]},{"type":"pipeline","name":"Santa Marta / Ayacucho","id":"Santa Marta / Ayacucho","econ":2,"adjacent":[5,11,17,18,19,47,48,49]},{"type":"pipeline","name":"Bucaramanga / Ayacucho","id":"Bucaramanga / Ayacucho","econ":2,"adjacent":[3,11,17,18,19,46,48,49]},{"type":"pipeline","name":"Sincelejo / Ayacucho","id":"Sincelejo / Ayacucho","econ":3,"adjacent":[10,11,17,18,19,46,47,49]},{"type":"pipeline","name":"Cúcuta / Ayacucho","id":"Cucuta / Ayacucho","econ":3,"adjacent":[7,11,17,18,19,31,46,47,48]}],"first_piece":[[0,3,3,33],[63,72],[102,108],[126,141]],"last_piece":[[2,2,32,62],[71,101],[107,125],[140,152]]}
if (typeof module !== 'undefined') module.exports = data
diff --git a/play.html b/play.html
index d5994e0..63b6e3c 100644
--- a/play.html
+++ b/play.html
@@ -49,6 +49,11 @@
<div class="role_user">-</div>
</div>
</div>
+ <div class="role" id="role_FARC">
+ <div class="role_name"><span>FARC</span>
+ <div class="role_user">-</div>
+ </div>
+ </div>
<div class="role" id="role_AUC">
<div class="role_name"><span>AUC</span>
<div class="role_user">-</div>
@@ -59,11 +64,6 @@
<div class="role_user">-</div>
</div>
</div>
- <div class="role" id="role_FARC">
- <div class="role_name"><span>FARC</span>
- <div class="role_user">-</div>
- </div>
- </div>
</div>
<div id="log"></div>
</aside>
@@ -147,13 +147,13 @@
<div id="pieces">
<div id="govt_cylinder" class="piece govt cylinder"></div>
+<div id="farc_cylinder" class="piece farc cylinder"></div>
<div id="auc_cylinder" class="piece auc cylinder"></div>
<div id="cartels_cylinder" class="piece cartels cylinder"></div>
-<div id="farc_cylinder" class="piece farc cylinder"></div>
<div id="govt_resources" class="piece govt cylinder"></div>
+<div id="farc_resources" class="piece farc cylinder"></div>
<div id="auc_resources" class="piece auc cylinder"></div>
<div id="cartels_resources" class="piece cartels cylinder"></div>
-<div id="farc_resources" class="piece farc cylinder"></div>
</div>
</div>
diff --git a/play.js b/play.js
index 89df679..a870869 100644
--- a/play.js
+++ b/play.js
@@ -1,6 +1,32 @@
// TODO: FARC zone
// TODO: terror markers
+// Factions
+const GOVT = 0
+const FARC = 1
+const AUC = 2
+const CARTELS = 3
+
+// Pieces
+const BASE = 0
+const GUERRILLA = 1
+const TROOPS = 2
+const POLICE = 3
+
+const first_piece = data.first_piece
+const last_piece = data.last_piece
+
+const first_pop = data.first_pop
+const first_city = data.first_city
+const last_city = data.last_city
+const first_dept = data.first_dept
+const last_pop = data.last_pop
+const last_dept = data.last_dept
+const first_foreign = data.first_foreign
+const last_foreign = data.last_foreign
+const first_loc = data.first_loc
+const last_loc = data.last_loc
+
// Spaces
const AVAILABLE = -1
@@ -18,16 +44,17 @@ const INELIGIBLE = 8
let ui = {
favicon: document.getElementById("favicon"),
header: document.querySelector("header"),
- player: {
- govt: document.getElementById("role_Government"),
- auc: document.getElementById("role_AUC"),
- cartels: document.getElementById("role_Cartels"),
- farc: document.getElementById("role_FARC"),
- },
+ player: [
+ document.getElementById("role_Government"),
+ document.getElementById("role_FARC"),
+ document.getElementById("role_AUC"),
+ document.getElementById("role_Cartels"),
+ ],
spaces: [],
control: [],
support: [],
sabotage: [],
+ terror: [],
next_card: document.getElementById("next_card"),
this_card: document.getElementById("this_card"),
deck_size: document.getElementById("deck_size"),
@@ -41,39 +68,26 @@ let ui = {
document.getElementById("SOP_C2"),
document.getElementById("SOP_PASS"),
],
- misc: {
+ tokens: {
aid: document.getElementById("token_aid"),
total_support: document.getElementById("token_total_support"),
oppose_plus_bases: document.getElementById("token_oppose_plus_bases"),
president: document.getElementById("token_el_presidente"),
propaganda: document.getElementById("token_prop_card"),
- shipments: [],
- },
- govt: {
- resources: document.getElementById("govt_resources"),
- cylinder: document.getElementById("govt_cylinder"),
- police: [],
- troops: [],
- bases: [],
- },
- auc: {
- resources: document.getElementById("auc_resources"),
- cylinder: document.getElementById("auc_cylinder"),
- guerrillas: [],
- bases: [],
- },
- cartels: {
- resources: document.getElementById("cartels_resources"),
- cylinder: document.getElementById("cartels_cylinder"),
- guerrillas: [],
- bases: [],
- },
- farc: {
- resources: document.getElementById("farc_resources"),
- cylinder: document.getElementById("farc_cylinder"),
- guerrillas: [],
- bases: [],
},
+ pieces: [],
+ resources: [
+ document.getElementById("govt_resources"),
+ document.getElementById("farc_resources"),
+ document.getElementById("auc_resources"),
+ document.getElementById("cartels_resources"),
+ ],
+ cylinder: [
+ document.getElementById("govt_cylinder"),
+ document.getElementById("farc_cylinder"),
+ document.getElementById("auc_cylinder"),
+ document.getElementById("cartels_cylinder"),
+ ],
}
function create(t, p, ...c) {
@@ -104,17 +118,6 @@ function on_click_action(evt) {
send_action(evt.target.my_action, evt.target.my_id)
}
-const first_pop = 1
-const first_city = 0
-const last_city = 10
-const first_dept = 11
-const last_pop = 22
-const last_dept = 26
-const first_foreign = 27
-const last_foreign = 31
-const first_loc = 32
-const last_loc = 49
-
const center_xy = {
"Santa Marta": [682,436],
"Cartagena": [500,512],
@@ -305,25 +308,38 @@ function init_ui() {
return e
}
- function create_piece_list(list, c, action, n, x, y) {
- for (let i = 0; i < n; ++i)
- list[i] = create_piece(c, action, i, x, y)
+ function create_piece_list(faction, type, c, x, y) {
+ for (let p = first_piece[faction][type]; p <= last_piece[faction][type]; ++p)
+ ui.pieces[p] = create_piece(c, "piece", p, x, y)
}
- create_piece_list(ui.misc.shipments, "token shipment", "shipment", 4, 0, 0)
+ ui.farc_zones = [
+ document.getElementById("tokens").appendChild(create("div", { className: "hide" })),
+ document.getElementById("tokens").appendChild(create("div", { className: "hide" })),
+ document.getElementById("tokens").appendChild(create("div", { className: "hide" })),
+ ]
- create_piece_list(ui.govt.police, "piece govt police", "govt_police", 30, 0, 4)
- create_piece_list(ui.govt.troops, "piece govt troops", "govt_troops", 30, 0, 4)
- create_piece_list(ui.govt.bases, "piece govt base", "govt_base", 3, -4, 10)
+ ui.shipments = [
+ create_piece("token shipment", "shipment", 0, 0, 0),
+ create_piece("token shipment", "shipment", 1, 0, 0),
+ create_piece("token shipment", "shipment", 2, 0, 0),
+ create_piece("token shipment", "shipment", 3, 0, 0),
+ ]
- create_piece_list(ui.auc.guerrillas, "piece auc guerrilla", "auc_guerrilla", 18, 2, 0)
- create_piece_list(ui.auc.bases, "piece auc base", "auc_base", 6, -4, 10)
+ ui.pieces = []
- create_piece_list(ui.cartels.guerrillas, "piece cartels guerrilla", "cartels_guerrilla", 12, 2, 0)
- create_piece_list(ui.cartels.bases, "piece cartels base", "cartels_base", 15, -4, 10)
+ create_piece_list(GOVT, BASE, "piece govt base", -4, 10)
+ create_piece_list(GOVT, POLICE, "piece govt police", 0, 4)
+ create_piece_list(GOVT, TROOPS, "piece govt troops", 0, 4)
- create_piece_list(ui.farc.guerrillas, "piece farc guerrilla", "farc_guerrilla", 30, 2, 0)
- create_piece_list(ui.farc.bases, "piece farc base", "farc_base", 9, -4, 10)
+ create_piece_list(FARC, BASE, "piece farc base", -4, 10)
+ create_piece_list(FARC, GUERRILLA, "piece farc guerrilla", 2, 0)
+
+ create_piece_list(AUC, BASE, "piece auc base", -4, 10)
+ create_piece_list(AUC, GUERRILLA, "piece auc guerrilla", 2, 0)
+
+ create_piece_list(CARTELS, GUERRILLA, "piece cartels guerrilla", 2, 0)
+ create_piece_list(CARTELS, BASE, "piece cartels base", -4, 10)
register_action(ui.sop[1], "sop", 1)
register_action(ui.sop[2], "sop", 2)
@@ -334,21 +350,15 @@ function init_ui() {
register_action(ui.sop[7], "sop", 7)
}
-function filter_piece_list(list, slist, elist, space) {
- for (let i = 0; i < slist.length; ++i)
- if (slist[i] === space)
- list.push(elist[i])
+function filter_piece_list(list, space, faction, type) {
+ for (let i = first_piece[faction][type]; i <= last_piece[faction][type]; ++i)
+ if (view.pieces[i] === space)
+ list.push(ui.pieces[i])
}
-function layout_cubes_available(slist, elist, space, xorig, yorig) {
+function layout_available(faction, type, xorig, yorig) {
let list = []
- filter_piece_list(list, slist, elist, space)
- layout_pieces(list, xorig, yorig)
-}
-
-function layout_guerrillas_available(slist, elist, space, xorig, yorig) {
- let list = []
- filter_piece_list(list, slist, elist, space)
+ filter_piece_list(list, AVAILABLE, faction, type)
layout_pieces(list, xorig, yorig)
}
@@ -424,14 +434,6 @@ const sop_xy = [
[SOP_C2, 1374-22, 632-24],
]
-const SHORT_LIST = [ "govt", "auc", "cartels", "farc" ]
-const SHORT = {
- "Government": "govt",
- "AUC": "auc",
- "Cartels": "cartels",
- "FARC": "farc",
-}
-
function layout_sop() {
let x, y, z
@@ -439,13 +441,10 @@ function layout_sop() {
x = 1164 - 22
y = 480
z = 1
- let order = data.cards[view.deck[0]].order
- if (!order)
- order = [ "Government", "AUC", "Cartels", "FARC" ]
+ let order = data.card_order[view.deck[0]]
for (let faction of order) {
- faction = SHORT[faction]
- if (view[faction].cylinder === ELIGIBLE) {
- place_piece(ui[faction].cylinder, x, y, z)
+ if (view.cylinder[faction] === ELIGIBLE) {
+ place_piece(ui.cylinder[faction], x, y, z)
y += 40
z += 1
}
@@ -455,9 +454,9 @@ function layout_sop() {
x = 1510 - 22
y = 480
z = 1
- for (let faction of SHORT_LIST) {
- if (view[faction].cylinder === INELIGIBLE) {
- place_piece(ui[faction].cylinder, x, y, z)
+ for (let faction = 0; faction < 4; ++faction) {
+ if (view.cylinder[faction] === INELIGIBLE) {
+ place_piece(ui.cylinder[faction], x, y, z)
y += 40
z += 1
}
@@ -468,9 +467,9 @@ function layout_sop() {
y = 688 - 28
z = 1
i = 0
- for (let faction of SHORT_LIST) {
- if (view[faction].cylinder === SOP_PASS) {
- place_piece(ui[faction].cylinder, x, y, z)
+ for (let faction = 0; faction < 4; ++faction) {
+ if (view.cylinder[faction] === SOP_PASS) {
+ place_piece(ui.cylinder[faction], x, y, z)
x += 48
z += 1
if (++i === 2) { x -= 72; y += 28 }
@@ -478,10 +477,9 @@ function layout_sop() {
}
for (let [i, x, y] of sop_xy) {
- if (view.govt.cylinder === i) place_piece(ui.govt.cylinder, x, y)
- if (view.auc.cylinder === i) place_piece(ui.auc.cylinder, x, y)
- if (view.cartels.cylinder === i) place_piece(ui.cartels.cylinder, x, y)
- if (view.farc.cylinder === i) place_piece(ui.farc.cylinder, x, y)
+ for (let faction = 0; faction < 4; ++faction)
+ if (view.cylinder[faction] === i)
+ place_piece(ui.cylinder[faction], x, y)
}
for (let i = 1; i <= 7; ++i) {
@@ -495,10 +493,10 @@ function layout_sop() {
function calc_oppose_bases() {
let total = 0
for (let s = 0; s <= last_pop; ++s) {
- if (view.misc.support[s] < 0)
- total -= data.spaces[s].pop * view.misc.support[s]
+ if (view.support[s] < 0)
+ total -= data.spaces[s].pop * view.support[s]
}
- for (let b of view.farc.bases)
+ for (let b = first_piece[FARC][BASE]; b <= last_piece[FARC][BASE]; ++b)
if (b !== AVAILABLE)
total += 1
return total
@@ -507,8 +505,8 @@ function calc_oppose_bases() {
function calc_support() {
let total = 0
for (let s = 0; s <= last_pop; ++s) {
- if (view.misc.support[s] > 0)
- total += data.spaces[s].pop * view.misc.support[s]
+ if (view.support[s] > 0)
+ total += data.spaces[s].pop * view.support[s]
}
return total
}
@@ -540,14 +538,12 @@ function layout_score() {
let total_support = calc_support()
let oppose_plus_bases = calc_oppose_bases()
- if (total_support === i) list.push(ui.misc.total_support)
- if (oppose_plus_bases === i) list.push(ui.misc.oppose_plus_bases)
- if (view.misc.aid === i) list.push(ui.misc.aid)
+ if (total_support === i) list.push(ui.tokens.total_support)
+ if (oppose_plus_bases === i) list.push(ui.tokens.oppose_plus_bases)
+ if (view.aid === i) list.push(ui.tokens.aid)
- if (view.govt.resources === i) list.push(ui.govt.resources)
- if (view.auc.resources === i) list.push(ui.auc.resources)
- if (view.cartels.resources === i) list.push(ui.cartels.resources)
- if (view.farc.resources === i) list.push(ui.farc.resources)
+ for (let faction = 0; faction < 4; ++faction)
+ if (view.resources[faction] === i) list.push(ui.resources[faction])
if (i <= 30) y = 16
else if (i >= 77) y = 2486
@@ -572,21 +568,42 @@ function layout_score() {
}
}
-function update_guerrillas_active(elts, guerrillas, active) {
- for (let i = 0; i < guerrillas.length; ++i) {
- if (active & (1 << i))
- elts[i].classList.add("active")
+function update_guerrillas_underground(faction, type, underground) {
+ let p0 = first_piece[faction][type]
+ let p1 = last_piece[faction][type]
+ for (let i = 0, p = p0; p <= p1; ++i, ++p) {
+ if (underground & (1 << i))
+ ui.pieces[p].classList.remove("active")
else
- elts[i].classList.remove("active")
+ ui.pieces[p].classList.add("active")
}
}
-function on_update() {
- ui.header.classList.toggle("govt", view.active === "Government")
- ui.header.classList.toggle("auc", view.active === "AUC")
- ui.header.classList.toggle("cartels", view.active === "Cartels")
- ui.header.classList.toggle("farc", view.active === "FARC")
+function action_piece_list(list, action) {
+ if (view.actions && view.actions[action]) {
+ for (let i = 0; i < list.length; ++i) {
+ if (set_has(view.actions[action], i)) {
+ list[i].classList.add("action")
+ } else {
+ list[i].classList.remove("action")
+ }
+ }
+ }
+}
+function layout_farc_zone(s, elt) {
+ let [x, y] = get_center_xy(s)
+ if (s <= last_pop) {
+ y -= 65
+ } else {
+ x += 55
+ }
+ elt.className = "token farc_zone"
+ elt.style.top = (y - 25) + "px"
+ elt.style.left = (x - 25) + "px"
+}
+
+function on_update() {
switch (player) {
case "Government": favicon.href = "images/icon_govt.png"; break
case "AUC": favicon.href = "images/icon_auc.png"; break
@@ -594,19 +611,24 @@ function on_update() {
case "FARC": favicon.href = "images/icon_farc.png"; break
}
- ui.misc.president.style.left = [ 0, "254px", "337px", "420px" ][view.misc.president]
+ ui.header.classList.toggle("govt", view.current === GOVT)
+ ui.header.classList.toggle("auc", view.current === AUC)
+ ui.header.classList.toggle("cartels", view.current === CARTELS)
+ ui.header.classList.toggle("farc", view.current === FARC)
- ui.player.govt.classList.toggle("active", view.active === "Government")
- ui.player.auc.classList.toggle("active", view.active === "AUC")
- ui.player.cartels.classList.toggle("active", view.active === "Cartels")
- ui.player.farc.classList.toggle("active", view.active === "FARC")
+ ui.player[GOVT].classList.toggle("active", view.current === GOVT)
+ ui.player[AUC].classList.toggle("active", view.current === AUC)
+ ui.player[CARTELS].classList.toggle("active", view.current === CARTELS)
+ ui.player[FARC].classList.toggle("active", view.current === FARC)
+
+ ui.tokens.president.style.left = [ 0, "254px", "337px", "420px" ][view.president]
if (view.propaganda > 0) {
- ui.misc.propaganda.style.top = "744px"
- ui.misc.propaganda.style.left = (1124 + 75 * (view.propaganda - 1)) + "px"
+ ui.tokens.propaganda.style.top = "744px"
+ ui.tokens.propaganda.style.left = (1124 + 75 * (view.propaganda - 1)) + "px"
} else {
- ui.misc.propaganda.style.top = "666px"
- ui.misc.propaganda.style.left = "1029px"
+ ui.tokens.propaganda.style.top = "666px"
+ ui.tokens.propaganda.style.left = "1029px"
}
ui.this_card.className = "card card_" + view.deck[0]
@@ -616,16 +638,19 @@ function on_update() {
layout_sop()
layout_score()
- layout_cubes_available(view.govt.troops, ui.govt.troops, AVAILABLE, 114, 248)
- layout_cubes_available(view.govt.police, ui.govt.police, AVAILABLE, 114, 448)
- layout_guerrillas_available(view.auc.guerrillas, ui.auc.guerrillas, AVAILABLE, 196, 2370)
- layout_guerrillas_available(view.cartels.guerrillas, ui.cartels.guerrillas, AVAILABLE, 1465, 1970)
- layout_guerrillas_available(view.farc.guerrillas, ui.farc.guerrillas, AVAILABLE, 1396, 234)
+ layout_available(GOVT, TROOPS, 114, 248)
+ layout_available(GOVT, POLICE, 114, 448)
+ layout_available(FARC, GUERRILLA, 1396, 234)
+ layout_available(AUC, GUERRILLA, 196, 2370)
+ layout_available(CARTELS, GUERRILLA, 1465, 1970)
+
+ for (let i = view.farc_zones.length; i < ui.farc_zones.length; ++i)
+ ui.farc_zones[i].className = "hide"
let list = []
for (let s = 0; s < data.spaces.length; ++s) {
if (s <= last_pop) {
- switch (view.misc.support[s]) {
+ switch (view.support[s]) {
case -2: ui.support[s].className = "token active_opposition"; break
case -1: ui.support[s].className = "token passive_opposition"; break
case 0: ui.support[s].className = "hide"; break
@@ -635,75 +660,85 @@ function on_update() {
}
if (s >= first_loc && s <= last_loc) {
- if (set_has(view.misc.sabotage, s))
+ if (set_has(view.sabotage, s))
ui.sabotage[s].className = "token sabotage"
else
ui.sabotage[s].className = "hide"
}
if (s <= last_dept) {
- if (set_has(view.misc.farc_zones, s))
- ui.control[s].className = "token farc_zone"
- else switch (view.misc.control[s]) {
- case 0: ui.control[s].className = "hide"; break
- case 1: ui.control[s].className = "token govt_control"; break
- case 2: ui.control[s].className = "token farc_control"; break
- }
+ for (let i = 0; i < view.farc_zones.length; ++i)
+ if (view.farc_zones[i] === s)
+ layout_farc_zone(s, ui.farc_zones[i])
+ if (view.govt_control & (1<<s))
+ ui.control[s].className = "token govt_control"
+ else if (view.farc_control & (1<<s))
+ ui.control[s].className = "token farc_control"
+ else
+ ui.control[s].className = "hide"
}
- update_guerrillas_active(ui.auc.guerrillas, view.auc.guerrillas, view.auc.active)
- update_guerrillas_active(ui.cartels.guerrillas, view.cartels.guerrillas, view.cartels.active)
- update_guerrillas_active(ui.farc.guerrillas, view.farc.guerrillas, view.farc.active)
+ update_guerrillas_underground(FARC, GUERRILLA, view.underground[FARC])
+ update_guerrillas_underground(AUC, GUERRILLA, view.underground[AUC])
+ update_guerrillas_underground(CARTELS, GUERRILLA, view.underground[CARTELS])
list.length = 0
- filter_piece_list(list, view.auc.guerrillas, ui.auc.guerrillas, s)
- filter_piece_list(list, view.cartels.guerrillas, ui.cartels.guerrillas, s)
- filter_piece_list(list, view.farc.guerrillas, ui.farc.guerrillas, s)
- filter_piece_list(list, view.govt.troops, ui.govt.troops, s)
- filter_piece_list(list, view.govt.police, ui.govt.police, s)
+ filter_piece_list(list, s, FARC, GUERRILLA)
+ filter_piece_list(list, s, AUC, GUERRILLA)
+ filter_piece_list(list, s, CARTELS, GUERRILLA)
+ filter_piece_list(list, s, GOVT, TROOPS)
+ filter_piece_list(list, s, GOVT, POLICE)
- // TODO: associate shipments with other piece, not space
- filter_piece_list(list, view.misc.shipments, ui.misc.shipments, s)
+ // TODO: shipments with other faction/piece, not space
let xy = get_layout_xy(s)
if (xy)
layout_pieces(list, xy[0], xy[1])
list.length = 0
- filter_piece_list(list, view.govt.bases, ui.govt.bases, s)
- filter_piece_list(list, view.auc.bases, ui.auc.bases, s)
- filter_piece_list(list, view.farc.bases, ui.farc.bases, s)
- filter_piece_list(list, view.cartels.bases, ui.cartels.bases, s)
+ filter_piece_list(list, s, GOVT, BASE)
+ filter_piece_list(list, s, FARC, BASE)
+ filter_piece_list(list, s, AUC, BASE)
+ filter_piece_list(list, s, CARTELS, BASE)
xy = get_center_xy(s)
if (xy)
layout_space_bases(list, xy[0], xy[1], s <= last_city ? get_layout_radius(s) : 0)
else
- console.log("NO SPACE", s, data.spaces[s].name)
+ console.log("NO SPACE", s, data.space_name[s])
ui.spaces[s].classList.toggle("action", is_action("space", s))
}
list.length = 0
- filter_piece_list(list, view.misc.shipments, ui.misc.shipments, AVAILABLE)
+ for (let i = 0; i < 4; ++i)
+ if (view.shipments[i] === AVAILABLE)
+ list.push(ui.shipments[i])
layout_available_bases(list, 1532, 1722, 2, 2, 89, 69)
list.length = 0
- filter_piece_list(list, view.govt.bases, ui.govt.bases, AVAILABLE)
+ filter_piece_list(list, AVAILABLE, GOVT, BASE)
layout_available_bases(list, 287 + 177, 371, 3, 1, 61, 0)
list.length = 0
- filter_piece_list(list, view.auc.bases, ui.auc.bases, AVAILABLE)
- layout_available_bases(list, 446 + 360, 2386, 6, 1, 61, 0)
+ filter_piece_list(list, AVAILABLE, FARC, BASE)
+ layout_available_bases(list, 446 + 543, 2295, 9, 1, 61, 0)
list.length = 0
- filter_piece_list(list, view.farc.bases, ui.farc.bases, AVAILABLE)
- layout_available_bases(list, 446 + 543, 2295, 9, 1, 61, 0)
+ filter_piece_list(list, AVAILABLE, AUC, BASE)
+ layout_available_bases(list, 446 + 360, 2386, 6, 1, 61, 0)
list.length = 0
- filter_piece_list(list, view.cartels.bases, ui.cartels.bases, AVAILABLE)
+ filter_piece_list(list, AVAILABLE, CARTELS, BASE)
layout_available_bases(list, 1373 + 183, 2117, 3, 5, 63, 63)
+ if (view.actions && view.actions.piece)
+ for (let i = 0; i < ui.pieces.length; ++i)
+ ui.pieces[i].classList.toggle("action", set_has(view.actions.piece, i))
+ else
+ for (let i = 0; i < ui.pieces.length; ++i)
+ ui.pieces[i].classList.remove("action")
+
action_button("train", "Train")
action_button("patrol", "Patrol")
action_button("sweep", "Sweep")
@@ -744,13 +779,13 @@ function on_blur_card_tip(c) {
function sub_card(match, p1) {
let x = p1 | 0
- let n = data.cards[x].name
+ let n = data.card_name[x]
return `<span class="tip" onmouseenter="on_focus_card_tip(${x})" onmouseleave="on_blur_card_tip(${x})" onclick="on_click_card_tip(${x})">${n}</span>`
}
function sub_space(match, p1) {
let x = p1 | 0
- let n = data.spaces[x].name
+ let n = data.space_name[x]
return `<span class="tip" onmouseenter="on_focus_space_tip(${x})" onmouseleave="on_blur_space_tip(${x})" onclick="on_click_space_tip(${x})">${n}</span>`
}
diff --git a/rules.js b/rules.js
index e08a270..49748e5 100644
--- a/rules.js
+++ b/rules.js
@@ -6,15 +6,44 @@ let view = null
const data = require("./data.js")
-const GOVT = "Government"
-const AUC = "AUC"
-const CARTELS = "Cartels"
-const FARC = "FARC"
-
-// For 3 and 2 player games
-const AUC_CARTELS = "AUC + Cartels"
-const GOVT_AUC = "Government + AUC"
-const FARC_CARTELS = "FARC + Cartels"
+// Role names
+const NAME_GOVT = "Government"
+const NAME_FARC = "FARC"
+const NAME_AUC = "AUC"
+const NAME_CARTELS = "Cartels"
+const NAME_GOVT_AUC = "Government + AUC"
+const NAME_FARC_CARTELS = "FARC + Cartels"
+const NAME_AUC_CARTELS = "AUC + Cartels"
+
+const faction_name = [ NAME_GOVT, NAME_FARC, NAME_AUC, NAME_CARTELS ]
+
+// Factions
+const GOVT = 0
+const FARC = 1
+const AUC = 2
+const CARTELS = 3
+
+// Pieces
+const BASE = 0
+const GUERRILLA = 1
+const TROOPS = 2
+const POLICE = 3
+
+const space_name = data.space_name
+
+const first_piece = data.first_piece
+const last_piece = data.last_piece
+
+const first_pop = data.first_pop
+const first_city = data.first_city
+const last_city = data.last_city
+const first_dept = data.first_dept
+const last_pop = data.last_pop
+const last_dept = data.last_dept
+const first_foreign = data.first_foreign
+const last_foreign = data.last_foreign
+const first_loc = data.first_loc
+const last_loc = data.last_loc
// Sequence of Play options
const ELIGIBLE = 0
@@ -34,28 +63,15 @@ const NEUTRAL = 0
const PASSIVE_OPPOSITION = -1
const ACTIVE_OPPOSITION = -2
-// Control ?
-const UNCONTROLLED = 0
-const CTL_GOVERNMENT = 1
-const CTL_AUC = 2
-const CTL_CARTELS = 3
-const CTL_FARC = 4
+// Control
+const CTL_NEUTRAL = 0
+const CTL_GOVT = 1
+const CTL_FARC = 2
const SAMPER = 1
const PASTRANA = 2
const URIBE = 3
-const first_pop = 1
-const first_city = 0
-const last_city = 10
-const first_dept = 11
-const last_pop = 22
-const last_dept = 26
-const first_foreign = 27
-const last_foreign = 31
-const first_loc = 32
-const last_loc = 49
-
const AVAILABLE = -1
// Cities
@@ -102,10 +118,10 @@ const COASTAL_SPACES = [ ATLANTICO, CHOCO, NARINO, CESAR ]
exports.roles = function (scenario) {
if (scenario.startsWith("2P"))
- return [ GOVT_AUC, FARC_CARTELS ]
+ return [ NAME_GOVT_AUC, NAME_FARC_CARTELS ]
if (scenario.startsWith("3P"))
- return [ GOVT, FARC, AUC_CARTELS ]
- return [ GOVT, AUC, CARTELS, FARC ]
+ return [ NAME_GOVT, NAME_FARC, NAME_AUC_CARTELS ]
+ return [ NAME_GOVT, NAME_FARC, NAME_AUC, NAME_CARTELS ]
}
exports.scenarios = [
@@ -122,22 +138,32 @@ exports.scenarios = [
function load_game(state) {
game = state
- if (game.scenario !== 4)
- game.active = game.save_active
}
function save_game() {
+ if (game.scenario === 4) {
+ if (game.current === GOVT)
+ game.active = NAME_GOVT
+ if (game.current === FARC)
+ game.active = NAME_FARC
+ if (game.current === AUC)
+ game.active = NAME_AUC
+ if (game.current === CARTELS)
+ game.active = NAME_CARTELS
+ }
if (game.scenario === 3) {
- game.save_active = game.active
- if (game.active === AUC || game.active === CARTELS)
- game.active = AUC_CARTELS
+ if (game.current === GOVT)
+ game.active = NAME_GOVT
+ if (game.current === FARC)
+ game.active = NAME_FARC
+ if (game.current === AUC || game.current === CARTELS)
+ game.active = NAME_AUC_CARTELS
}
if (game.scenario === 2) {
- game.save_active = game.active
- if (game.active === GOVT || game.active === AUC)
- game.active = GOVT_AUC
- if (game.active === FARC || game.active === CARTELS)
- game.active = FARC_CARTELS
+ if (game.current === GOVT || game.current === AUC)
+ game.active = NAME_GOVT_AUC
+ if (game.current === FARC || game.current === CARTELS)
+ game.active = NAME_FARC_CARTELS
}
return game
}
@@ -147,53 +173,29 @@ exports.setup = function (seed, scenario, options) {
seed,
log: [],
undo: [],
+ active: null,
scenario: 4,
- active: null,
+ current: 0,
state: null,
op_spaces: null,
sa_spaces: null,
deck: [],
- misc: {
- aid: 0,
- president: 0,
- shipments: [ AVAILABLE, AVAILABLE, AVAILABLE, AVAILABLE ],
- control: Array(27).fill(0),
- support: Array(23).fill(NEUTRAL),
- farc_zones: [],
- terror: [],
- sabotage: [],
- },
- govt: {
- cylinder: ELIGIBLE,
- resources: 0,
- troops: Array(30).fill(AVAILABLE),
- police: Array(30).fill(AVAILABLE),
- bases: Array(3).fill(AVAILABLE),
- },
- auc: {
- cylinder: ELIGIBLE,
- resources: 0,
- guerrillas: Array(18).fill(AVAILABLE),
- bases: Array(6).fill(AVAILABLE),
- active: 0,
- },
- cartels: {
- cylinder: ELIGIBLE,
- resources: 0,
- guerrillas: Array(12).fill(AVAILABLE),
- bases: Array(15).fill(AVAILABLE),
- active: 0,
- },
- farc: {
- cylinder: ELIGIBLE,
- resources: 0,
- guerrillas: Array(30).fill(AVAILABLE),
- bases: Array(9).fill(AVAILABLE),
- active: 0,
- },
+ president: 0,
+ aid: 0,
+ cylinder: [ ELIGIBLE, ELIGIBLE, ELIGIBLE, ELIGIBLE ],
+ resources: [ 0, 0, 0, 0 ],
+ shipments: [ AVAILABLE, AVAILABLE, AVAILABLE, AVAILABLE ],
+ pieces: Array(153).fill(AVAILABLE),
+ underground: [ 0, 0, -1, -1 ],
+ farc_control: 0,
+ govt_control: 0,
+ support: Array(23).fill(NEUTRAL),
+ farc_zones: [],
+ terror: [],
+ sabotage: [],
}
if (scenario.startsWith("3P"))
@@ -229,12 +231,12 @@ exports.setup = function (seed, scenario, options) {
}
function setup_standard() {
- game.misc.aid = 9
- game.misc.president = SAMPER
- game.govt.resources = 40
- game.auc.resources = 10
- game.cartels.resources = 10
- game.farc.resources = 10
+ game.aid = 9
+ game.president = SAMPER
+ game.resources[GOVT] = 40
+ game.resources[AUC] = 10
+ game.resources[CARTELS] = 10
+ game.resources[FARC] = 10
set_support(ATLANTICO, ACTIVE_SUPPORT)
set_support(SANTANDER, ACTIVE_SUPPORT)
@@ -250,81 +252,81 @@ function setup_standard() {
set_support(PUTUMAYO, ACTIVE_OPPOSITION)
set_support(NARINO, ACTIVE_OPPOSITION)
- place_piece(game.govt.troops, 3, BOGOTA)
- place_piece(game.govt.troops, 3, MEDELLIN)
- place_piece(game.govt.troops, 3, CALI)
- place_piece(game.govt.troops, 3, SANTANDER)
- place_piece(game.govt.police, 2, BOGOTA)
+ place_piece(GOVT, TROOPS, 3, BOGOTA)
+ place_piece(GOVT, TROOPS, 3, MEDELLIN)
+ place_piece(GOVT, TROOPS, 3, CALI)
+ place_piece(GOVT, TROOPS, 3, SANTANDER)
+ place_piece(GOVT, POLICE, 2, BOGOTA)
for (let s = first_city; s <= last_city; ++s)
if (s !== BOGOTA)
- place_piece(game.govt.police, 1, s)
- place_piece(game.govt.bases, 1, SANTANDER)
-
- place_piece(game.farc.guerrillas, 1, NARINO)
- place_piece(game.farc.guerrillas, 1, CHOCO)
- place_piece(game.farc.guerrillas, 1, SANTANDER)
- place_piece(game.farc.guerrillas, 1, HUILA)
- place_piece(game.farc.guerrillas, 1, ARAUCA)
- place_piece(game.farc.guerrillas, 1, META_EAST)
- place_piece(game.farc.guerrillas, 2, META_WEST)
- place_piece(game.farc.guerrillas, 2, GUAVIARE)
- place_piece(game.farc.guerrillas, 2, PUTUMAYO)
- place_piece(game.farc.bases, 1, CHOCO)
- place_piece(game.farc.bases, 1, HUILA)
- place_piece(game.farc.bases, 1, ARAUCA)
- place_piece(game.farc.bases, 1, META_EAST)
- place_piece(game.farc.bases, 1, META_WEST)
- place_piece(game.farc.bases, 1, GUAVIARE)
-
- place_piece(game.auc.guerrillas, 1, ATLANTICO)
- place_piece(game.auc.guerrillas, 1, ANTIOQUIA)
- place_piece(game.auc.guerrillas, 1, SANTANDER)
- place_piece(game.auc.guerrillas, 1, ARAUCA)
- place_piece(game.auc.guerrillas, 1, GUAVIARE)
- place_piece(game.auc.guerrillas, 1, PUTUMAYO)
- place_piece(game.auc.bases, 1, ANTIOQUIA)
-
- place_piece(game.cartels.guerrillas, 1, CALI)
- place_piece(game.cartels.guerrillas, 1, PUTUMAYO)
- place_piece(game.cartels.bases, 1, CALI)
- place_piece(game.cartels.bases, 1, META_EAST)
- place_piece(game.cartels.bases, 1, META_WEST)
- place_piece(game.cartels.bases, 1, GUAVIARE)
- place_piece(game.cartels.bases, 2, PUTUMAYO)
+ place_piece(GOVT, POLICE, 1, s)
+ place_piece(GOVT, BASE, 1, SANTANDER)
+
+ place_piece(FARC, GUERRILLA, 1, NARINO)
+ place_piece(FARC, GUERRILLA, 1, CHOCO)
+ place_piece(FARC, GUERRILLA, 1, SANTANDER)
+ place_piece(FARC, GUERRILLA, 1, HUILA)
+ place_piece(FARC, GUERRILLA, 1, ARAUCA)
+ place_piece(FARC, GUERRILLA, 1, META_EAST)
+ place_piece(FARC, GUERRILLA, 2, META_WEST)
+ place_piece(FARC, GUERRILLA, 2, GUAVIARE)
+ place_piece(FARC, GUERRILLA, 2, PUTUMAYO)
+ place_piece(FARC, BASE, 1, CHOCO)
+ place_piece(FARC, BASE, 1, HUILA)
+ place_piece(FARC, BASE, 1, ARAUCA)
+ place_piece(FARC, BASE, 1, META_EAST)
+ place_piece(FARC, BASE, 1, META_WEST)
+ place_piece(FARC, BASE, 1, GUAVIARE)
+
+ place_piece(AUC, GUERRILLA, 1, ATLANTICO)
+ place_piece(AUC, GUERRILLA, 1, ANTIOQUIA)
+ place_piece(AUC, GUERRILLA, 1, SANTANDER)
+ place_piece(AUC, GUERRILLA, 1, ARAUCA)
+ place_piece(AUC, GUERRILLA, 1, GUAVIARE)
+ place_piece(AUC, GUERRILLA, 1, PUTUMAYO)
+ place_piece(AUC, BASE, 1, ANTIOQUIA)
+
+ place_piece(CARTELS, GUERRILLA, 1, CALI)
+ place_piece(CARTELS, GUERRILLA, 1, PUTUMAYO)
+ place_piece(CARTELS, BASE, 1, CALI)
+ place_piece(CARTELS, BASE, 1, META_EAST)
+ place_piece(CARTELS, BASE, 1, META_WEST)
+ place_piece(CARTELS, BASE, 1, GUAVIARE)
+ place_piece(CARTELS, BASE, 2, PUTUMAYO)
}
function setup_quick() {
- place_piece(game.cartels.guerrillas, 4, MEDELLIN)
- place_piece(game.cartels.bases, 1, MEDELLIN)
+ place_piece(CARTELS, GUERRILLA, 4, MEDELLIN)
+ place_piece(CARTELS, BASE, 1, MEDELLIN)
set_support(CALI, ACTIVE_SUPPORT)
- place_piece(game.govt.police, 4, CALI)
- remove_piece(game.cartels.guerrillas, 1, CALI)
- remove_piece(game.cartels.bases, 1, CALI)
+ place_piece(GOVT, POLICE, 4, CALI)
+ remove_piece(CARTELS, GUERRILLA, 1, CALI)
+ remove_piece(CARTELS, BASE, 1, CALI)
- place_piece(game.govt.troops, 6, BOGOTA)
+ place_piece(GOVT, TROOPS, 6, BOGOTA)
- place_piece(game.auc.bases, 1, SANTANDER)
+ place_piece(AUC, BASE, 1, SANTANDER)
set_support(ARAUCA, NEUTRAL)
- place_piece(game.auc.guerrillas, 1, ARAUCA)
+ place_piece(AUC, GUERRILLA, 1, ARAUCA)
- set_add(game.misc.farc_zones, META_WEST)
- place_piece(game.farc.guerrillas, 4, META_WEST)
+ set_add(game.farc_zones, META_WEST)
+ place_piece(FARC, GUERRILLA, 4, META_WEST)
set_support(HUILA, ACTIVE_OPPOSITION)
- place_piece(game.farc.guerrillas, 3, HUILA)
- place_piece(game.auc.guerrillas, 2, HUILA)
- place_piece(game.cartels.bases, 1, HUILA)
+ place_piece(FARC, GUERRILLA, 3, HUILA)
+ place_piece(AUC, GUERRILLA, 2, HUILA)
+ place_piece(CARTELS, BASE, 1, HUILA)
- place_piece(game.farc.guerrillas, 2, VAUPES)
+ place_piece(FARC, GUERRILLA, 2, VAUPES)
- game.auc.resources = 5
- game.farc.resources = 10
- game.cartels.resources = 20
- game.govt.resources = 30
+ game.resources[AUC] = 5
+ game.resources[FARC] = 10
+ game.resources[CARTELS] = 20
+ game.resources[GOVT] = 30
- game.misc.president = PASTRANA
+ game.president = PASTRANA
}
function shuffle_all_cards() {
@@ -359,60 +361,93 @@ function setup_deck(count, a, b) {
}
function set_support(place, amount) {
- game.misc.support[place] = amount
+ game.support[place] = amount
}
function get_support(place, amount) {
- return game.misc.support[place]
+ return game.support[place]
}
-function place_piece(list, count, where) {
- for (let i = 0; i < list.length && count > 0; ++i) {
- if (list[i] < 0) {
- list[i] = where
+function place_piece(faction, type, count, where) {
+ for (let p = first_piece[faction][type]; count > 0; ++p) {
+ if (game.pieces[p] < 0) {
+ game.pieces[p] = where
--count
}
}
- if (count !== 0)
- throw Error("bad piece count")
}
-function remove_piece(list, count, where) {
- for (let i = 0; i < list.length && count > 0; ++i) {
- if (list[i] === where) {
- list[i] = AVAILABLE
+function remove_piece(faction, type, count, where) {
+ for (let p = first_piece[faction][type]; count > 0; ++p) {
+ if (game.pieces[p] === where) {
+ game.pieces[p] = AVAILABLE
--count
}
}
- if (count !== 0)
- throw Error("bad piece count")
}
-function count_pieces_imp(s, list) {
+function count_pieces_imp(s, faction, type) {
+ let first = first_piece[faction][type]
+ let last = last_piece[faction][type]
let n = 0
- for (let i = 0; i < list.length; ++i)
- if (list[i] === s)
+ for (let p = first; p <= last; ++p)
+ if (game.pieces[p] === s)
++n
return n
}
function update_control() {
+ game.govt_control = 0
+ game.farc_control = 0
for (let s = 0; s <= last_dept; ++s) {
- let g = count_pieces_imp(s, game.govt.troops) +
- count_pieces_imp(s, game.govt.police) +
- count_pieces_imp(s, game.govt.bases)
- let a = count_pieces_imp(s, game.auc.guerrillas) +
- count_pieces_imp(s, game.auc.bases)
- let c = count_pieces_imp(s, game.cartels.guerrillas) +
- count_pieces_imp(s, game.cartels.bases)
- let f = count_pieces_imp(s, game.farc.guerrillas) +
- count_pieces_imp(s, game.farc.bases)
+ let g = count_pieces_imp(s, GOVT, BASE) +
+ count_pieces_imp(s, GOVT, TROOPS) +
+ count_pieces_imp(s, GOVT, POLICE)
+ let f = count_pieces_imp(s, FARC, BASE) +
+ count_pieces_imp(s, FARC, GUERRILLA)
+ let a = count_pieces_imp(s, AUC, BASE) +
+ count_pieces_imp(s, AUC, GUERRILLA)
+ let c = count_pieces_imp(s, CARTELS, BASE) +
+ count_pieces_imp(s, CARTELS, GUERRILLA)
if (g > a + c + f)
- game.misc.control[s] = 1
+ game.govt_control |= (1 << s)
else if (f > g + a + c)
- game.misc.control[s] = 2
- else
- game.misc.control[s] = 0
+ game.farc_control |= (1 << s)
+ }
+}
+
+function is_city(s) {
+ return s <= last_city
+}
+
+function has_govt_base(s) {
+ return set_has(game.govt.bases, s)
+}
+
+function is_underground(p) {
+ for (let faction = 1; faction < 4; ++faction) {
+ let p0 = first_piece[faction][GUERRILLA]
+ let p1 = last_piece[faction][GUERRILLA]
+ if (p >= p0 && p <= p1)
+ return game.underground[faction] & (1 << (p - p0))
+ }
+}
+
+function set_underground(p) {
+ for (let faction = 1; faction < 4; ++faction) {
+ let p0 = first_piece[faction][GUERRILLA]
+ let p1 = last_piece[faction][GUERRILLA]
+ if (p >= p0 && p <= p1)
+ game.underground[faction] |= (1 << (p - p0))
+ }
+}
+
+function set_active(p) {
+ for (let faction = 1; faction < 4; ++faction) {
+ let p0 = first_piece[faction][GUERRILLA]
+ let p1 = last_piece[faction][GUERRILLA]
+ if (p >= p0 && p <= p1)
+ game.underground[faction] &= ~(1 << (p - p0))
}
}
@@ -430,44 +465,29 @@ function goto_card() {
}
function adjust_eligibility(faction) {
- if (faction.cylinder === INELIGIBLE || faction.cylinder === SOP_PASS)
- faction.cylinder = ELIGIBLE
- else if (faction.cylinder !== ELIGIBLE)
- faction.cylinder = INELIGIBLE
+ if (game.cylinder[faction] === INELIGIBLE || game.cylinder[faction] === SOP_PASS)
+ game.cylinder[faction] = ELIGIBLE
+ else if (game.cylinder[faction] !== ELIGIBLE)
+ game.cylinder[faction] = INELIGIBLE
}
function end_card() {
- adjust_eligibility(game.govt)
- adjust_eligibility(game.auc)
- adjust_eligibility(game.cartels)
- adjust_eligibility(game.farc)
+ adjust_eligibility(GOVT)
+ adjust_eligibility(FARC)
+ adjust_eligibility(AUC)
+ adjust_eligibility(CARTELS)
clear_undo()
array_remove(game.deck, 0)
goto_card()
}
-function current_faction() {
- switch (game.active) {
- case GOVT: return game.govt
- case AUC: return game.auc
- case CARTELS: return game.cartels
- case FARC: return game.farc
- }
-}
-
function is_eligible(faction) {
- switch (faction) {
- case GOVT: return game.govt.cylinder === ELIGIBLE
- case AUC: return game.auc.cylinder === ELIGIBLE
- case CARTELS: return game.cartels.cylinder === ELIGIBLE
- case FARC: return game.farc.cylinder === ELIGIBLE
- }
- return false
+ return game.cylinder[faction] === ELIGIBLE
}
function next_eligible_faction() {
- let order = data.cards[this_card()].order
+ let order = data.card_order[this_card()]
for (let faction of order)
if (is_eligible(faction))
return faction
@@ -476,10 +496,10 @@ function next_eligible_faction() {
function did_option(e) {
return (
- game.govt.cylinder === e ||
- game.auc.cylinder === e ||
- game.cartels.cylinder === e ||
- game.farc.cylinder === e
+ game.cylinder[GOVT] === e ||
+ game.cylinder[FARC] === e ||
+ game.cylinder[AUC] === e ||
+ game.cylinder[CARTELS] === e
)
}
@@ -503,16 +523,16 @@ function resume_event_card() {
}
function goto_eligible1() {
- game.active = next_eligible_faction()
- if (game.active === null)
+ game.current = next_eligible_faction()
+ if (game.current === null)
end_card()
else
game.state = "eligible1"
}
function goto_eligible2() {
- game.active = next_eligible_faction()
- if (game.active === null)
+ game.current = next_eligible_faction()
+ if (game.current === null)
end_card()
else
game.state = "eligible2"
@@ -527,11 +547,10 @@ states.eligible1 = {
gen_action("sop", SOP_1ST_EVENT)
gen_action("sop", SOP_PASS)
},
- sop(e) {
+ sop(option) {
push_undo()
- let faction = current_faction()
- faction.cylinder = e
- switch (e) {
+ game.cylinder[game.current] = option
+ switch (option) {
case SOP_PASS:
goto_pass()
break
@@ -560,11 +579,10 @@ states.eligible2 = {
gen_action("sop", SOP_2ND_OP_AND_SA)
gen_action("sop", SOP_PASS)
},
- sop(e) {
+ sop(option) {
push_undo()
- let faction = current_faction()
- faction.cylinder = e
- switch (e) {
+ game.cylinder[game.current] = option
+ switch (option) {
case SOP_PASS:
goto_pass()
break
@@ -582,12 +600,11 @@ states.eligible2 = {
}
function goto_pass() {
- log_h2(game.active + " - Pass")
- let faction = current_faction()
- if (game.active === GOVT)
- faction.resources += 3
+ log_h2(faction_name[game.current] + " - Pass")
+ if (game.current === GOVT)
+ game.resources[game.current] += 3
else
- faction.resources += 1
+ game.resources[game.current] += 1
resume_event_card()
}
@@ -611,27 +628,27 @@ states.limop_or_event = {
}
function goto_event() {
- log_h2(game.active + " - Event")
+ log_h2(faction_name[game.current] + " - Event")
log("TODO: Event")
resume_event_card()
}
function goto_op_only() {
- log_h2(game.active + " - Op only")
+ log_h2(faction_name[game.current] + " - Op Only")
game.state = "op"
game.op_spaces = []
game.sa_spaces = null
}
function goto_op_and_sa() {
- log_h2(game.active + " - Op + Special")
+ log_h2(faction_name[game.current] + " - Op + Special")
game.state = "op"
game.op_spaces = []
game.sa_spaces = []
}
function goto_limop() {
- log_h2(game.active + " - LimOp")
+ log_h2(faction_name[game.current] + " - LimOp")
game.state = "op"
game.op_spaces = []
game.sa_spaces = null
@@ -647,7 +664,7 @@ function can_use_special_activity() {
states.op = {
prompt() {
view.prompt = "Choose an Operation."
- if (game.active === GOVT) {
+ if (game.current === GOVT) {
view.actions.train = 1
view.actions.patrol = 1
view.actions.sweep = 1
@@ -658,6 +675,7 @@ states.op = {
view.actions.attack = 1
view.actions.terror = 1
}
+ view.actions.remove = 1
},
train() {
@@ -701,6 +719,35 @@ states.op = {
log_h3("Terror")
game.state = "terror"
},
+
+ remove() {
+ push_undo()
+ game.save_state = game.state
+ game.state = "remove"
+ },
+}
+
+function for_each_own_piece(f) {
+ f(p)
+}
+
+states.remove = {
+ prompt() {
+ view.prompt = "Remove pieces to Available Forces."
+ for_each_own_piece(p => {
+ if (game.pieces[p] !== AVAILABLE)
+ gen_action("piece", p)
+ })
+ view.actions.done = 1
+ },
+ piece(p) {
+ push_undo()
+ game.pieces[p] = AVAILABLE
+ },
+ done() {
+ game.state = game.save_state
+ game.save_state = 0
+ }
}
states.train = {
@@ -736,6 +783,36 @@ states.train = {
let faction = current_faction()
faction.resources -= 3
set_add(game.op_spaces, s)
+ game.where = s
+ if (is_city(s) || has_govt_base(s)) {
+ game.state = "train_place_cubes"
+ game.selected = -1
+ game.count = 6
+ } else {
+ game.state = "train_base_or_civic"
+ }
+ },
+}
+
+function gen_select_available(action, list) {
+ for (let i = list.length; i-- > 0; ) {
+ if (list[i] === AVAILABLE) {
+ gen_action(action, i)
+ return
+ }
+ }
+ for (let i = 0; i < list.length; ++i)
+ gen_action(action, i)
+}
+
+states.train_place_cubes = {
+ prompt() {
+ view.prompt = `Train in ${space_name[game.where]}: Place up to ${game.count} cubes.`
+
+ if (game.selected < 0) {
+ gen_select_available("govt_police", game.govt.police)
+ gen_select_available("govt_troops", game.govt.troops)
+ }
},
}
@@ -744,6 +821,7 @@ states.train = {
function goto_game_over(result, victory) {
game = { ...game } // make a copy so we can add properties!
game.state = "game_over"
+ game.current = -1
game.active = "None"
game.result = result
game.victory = victory
@@ -804,20 +882,27 @@ function gen_action(action, argument) {
set_add(view.actions[action], argument)
}
-function is_current_active(current) {
- switch (current) {
- case GOVT_AUC:
- return game.active === GOVT || game.active === AUC
- case FARC_CARTELS:
- return game.active === FARC || game.active === CARTELS
- case AUC_CARTELS:
- return game.active === AUC || game.active === CARTELS
- default:
- return game.active === current
+function is_current_role(role) {
+ switch (role) {
+ case NAME_GOVT_AUC:
+ return game.current === GOVT || game.current === AUC
+ case NAME_FARC_CARTELS:
+ return game.current === FARC || game.current === CARTELS
+ case NAME_AUC_CARTELS:
+ return game.current === AUC || game.current === CARTELS
+ case NAME_GOVT:
+ return game.current === GOVT
+ case NAME_FARC:
+ return game.current === FARC
+ case NAME_AUC:
+ return game.current === AUC
+ case NAME_CARTELS:
+ return game.current === CARTELS
}
+ return false
}
-exports.view = function (state, current) {
+exports.view = function (state, role) {
load_game(state)
let this_card = game.deck[0]
@@ -825,31 +910,37 @@ exports.view = function (state, current) {
let deck_size = Math.max(0, game.deck.length - 2)
view = {
- active: game.active,
prompt: null,
actions: null,
log: game.log,
+ current: game.current,
deck: [ this_card, next_card, deck_size ],
- op_spaces: game.op_spaces,
- sa_spaces: game.sa_spaces,
- misc: game.misc,
- govt: game.govt,
- auc: game.auc,
- cartels: game.cartels,
- farc: game.farc,
+ president: game.president,
+ aid: game.aid,
+ cylinder: game.cylinder,
+ resources: game.resources,
+ shipments: game.shipments,
+ pieces: game.pieces,
+ underground: game.underground,
+ govt_control: game.govt_control,
+ farc_control: game.farc_control,
+ support: game.support,
+ farc_zones: game.farc_zones,
+ terror: game.terror,
+ sabotage: game.sabotage,
}
if (game.state === "game_over") {
view.prompt = game.victory
- } else if (current === "Observer" || !is_current_active(current)) {
+ } else if (!is_current_role(role)) {
let inactive = states[game.state].inactive || game.state
- view.prompt = `Waiting for ${game.active} \u2014 ${inactive}.`
+ view.prompt = `Waiting for ${faction_name[game.current]} \u2014 ${inactive}.`
} else {
view.actions = {}
view.who = game.who
if (states[game.state])
- states[game.state].prompt(current)
+ states[game.state].prompt()
else
view.prompt = "Unknown state: " + game.state
if (view.actions.undo === undefined) {
@@ -864,12 +955,12 @@ exports.view = function (state, current) {
return view
}
-exports.action = function (state, current, action, arg) {
+exports.action = function (state, role, action, arg) {
load_game(state)
- Object.seal(game) // XXX: don't allow adding properties
+ // Object.seal(game) // XXX: don't allow adding properties
let S = states[game.state]
if (S && action in S) {
- S[action](arg, current)
+ S[action](arg)
} else {
if (action === "undo" && game.undo && game.undo.length > 0)
pop_undo()
diff --git a/tools/gendata.js b/tools/gendata.js
index 5d59674..e7f5df6 100644
--- a/tools/gendata.js
+++ b/tools/gendata.js
@@ -2,18 +2,30 @@ let fs = require("fs")
let data = {}
+const GOVT = 0
+const FARC = 1
+const AUC = 2
+const CARTELS = 3
+
+const BASE = 0
+const GUERRILLA = 1
+const TROOPS = 2
+const POLICE = 3
+
function to_ascii(s) {
return s.normalize("NFD").replace(/[\u0300-\u036f]/g, "")
}
-const IMAP = { G: "Government", F: "FARC", A: "AUC", C: "Cartels" }
+const IMAP = { G: GOVT, F: FARC, A: AUC, C: CARTELS }
let order = null
-let cards = [ null ]
+let card_name = [ null ]
+let card_order = [ null ]
function def_order(s) {
order = [ IMAP[s[0]], IMAP[s[1]], IMAP[s[2]], IMAP[s[3]] ]
}
function def_card(number, name) {
- cards[number] = { number, name, order }
+ card_name[number] = name
+ card_order[number] = order
}
def_order("GFAC")
def_card(1, "1st Division")
@@ -111,14 +123,15 @@ def_order("CAFG")
def_card(70, "Ayahuasca Tourism")
def_card(71, "Darién")
def_card(72, "Sicarios")
-order = null
+
+def_order("GFAC")
def_card(73, "Propaganda!")
def_card(74, "Propaganda!")
def_card(75, "Propaganda!")
def_card(76, "Propaganda!")
let spaces = [ ]
-let space_names = [ ]
+let space_name = [ ]
function add(list, item) {
if (!list.includes(item))
@@ -126,31 +139,31 @@ function add(list, item) {
}
function def_space(type, pop, name) {
- spaces.push({ type, id: to_ascii(name), name, pop, adjacent: [] })
- space_names.push(name)
+ spaces.push({ type, id: to_ascii(name), pop, adjacent: [] })
+ space_name.push(name)
}
function def_town(name) {
- spaces.push({ type: "town", id: to_ascii(name), name, adjacent: [] })
- space_names.push(name)
+ spaces.push({ type: "town", id: to_ascii(name), adjacent: [] })
+ space_name.push(name)
}
function def_loc(type, econ, cities, depts) {
let name = cities.join(" / ")
let loc_names = cities.concat(depts)
- let loc_spaces = loc_names.map(n => space_names.indexOf(n))
+ let loc_spaces = loc_names.map(n => space_name.indexOf(n))
let ix = spaces.length
spaces.push({ type, name, id: to_ascii(name), econ, adjacent: loc_spaces.filter(x=>x>0) })
for (let loc of loc_spaces)
if (loc >= 0)
add(spaces[loc].adjacent, ix)
- space_names.push(name)
+ space_name.push(name)
return ix
}
function adjacent(an, bn) {
- ax = space_names.indexOf(an)
- bx = space_names.indexOf(bn)
+ ax = space_name.indexOf(an)
+ bx = space_name.indexOf(bn)
add(spaces[ax].adjacent, bx)
add(spaces[bx].adjacent, ax)
}
@@ -379,12 +392,34 @@ adjacent("Vaupés", "Guaviare")
adjacent("Amazonas", "Vaupés")
adjacent("Amazonas", "Putumayo")
-data.coastal_spaces = [ "Cesar", "Atlántico", "Chocó", "Nariño" ].map(n=>space_names.indexOf(n)).sort((a,b)=>a-b)
+data.coastal_spaces = [ "Cesar", "Atlántico", "Chocó", "Nariño" ].map(n=>space_name.indexOf(n)).sort((a,b)=>a-b)
for (let i = 1; i < spaces.length; ++i)
spaces[i].adjacent.sort((a,b)=>a-b)
-data.cards = cards
+
+data.card_name = card_name
+data.card_order = card_order
+data.space_name = space_name
data.spaces = spaces
-fs.writeFileSync("data.js", "const data = " + JSON.stringify(data, 0, "\t") + "\nif (typeof module !== 'undefined') module.exports = data\n")
+let pc_index = 0
+let pc_first = data.first_piece = [ [ 0, 0, 0, 0 ], [ 0, 0 ], [ 0, 0 ], [ 0, 0 ] ]
+let pc_last = data.last_piece = [ [ -1, -1, -1, -1 ], [ -1, -1 ], [ -1, -1 ], [ -1, -1 ] ]
+function def_piece(faction, type, count) {
+ pc_first[faction][type] = pc_index
+ pc_last[faction][type] = pc_index + count - 1
+ pc_index += count
+}
+def_piece(GOVT, BASE, 3)
+def_piece(GOVT, GUERRILLA, 0)
+def_piece(GOVT, TROOPS, 30)
+def_piece(GOVT, POLICE, 30)
+def_piece(FARC, BASE, 9)
+def_piece(FARC, GUERRILLA, 30)
+def_piece(AUC, BASE, 6)
+def_piece(AUC, GUERRILLA, 18)
+def_piece(CARTELS, BASE, 15)
+def_piece(CARTELS, GUERRILLA, 12)
+
+fs.writeFileSync("data.js", "const data = " + JSON.stringify(data, 0, 0) + "\nif (typeof module !== 'undefined') module.exports = data\n")