all repos — uStrat @ 45157da9bf2ee40aac8ad1e5310fbe73eb0fbc3d

simple turn-based strategy game inspired by uCity, Super Robot Wars, C&C, Fire Emblem

implemented some remedial AI equipment logic. freezing this repo to refactor into typescript
Iris Lightshard nilix@nilfm.cc
PGP Signature
-----BEGIN PGP SIGNATURE-----

iQJDBAABCAAtFiEEkFh6dA+k/6CXFXU4O3+8IhROY5gFAl1+dEkPHG5pbGl4QG5p
bGZtLmNjAAoJEDt/vCIUTmOY7PIP/iTF+1QqR8MV5xDJnvquYhql3l5+Zgk+nmS9
aC4Pf3DrGkaZoE2/OHcZTOwxj1XwLbt6pA5clWPMx1/gR936mwXshk+G1kvPkyq5
pU9jQmSTxmNs6EqkaD7u8wNjooRoquqmQuKxlkyN5cX4Uan5f+KoXZOHHGhmL/w4
IhlC7Aa372PtfTDEl1W9b7Avvt85G8NyM5JqhG9cbMC/UFcMgAw7reNN4KWzVRKK
KvtEd2kweJJzFYoOhd639ZJDiwHP5RUrCqqTKHA1wfnM68v6ljewBj0cr1xPBymk
EMs1CFsU8SdM5uAVGWCbQbJcD/Mjn5mC6ZnQxF/nvYeacZ82HukPOn8GCzG1zNvK
PqhSxGN1pXrBHb0q2ev11GH7McA0ApthVX7amxdPC9N3j1Dc2/8qo3tp7rAMHMbI
m02mBb1P9wVvsyK0v4XjNHMzI7aTHFjMUM7t7c92z7g9TDfESlhEuXUPNtMPzoBL
tLg9vrO+mSb3v9A3c43NZa+c/WaUPmvcMssG1WbbQVFrgoc4DjA17OINSY1V21nb
DTAraTMfr+4WE6BMei23Ooo3u3mJ1AEEsC6oGMXB/HxSVTAP/z3ECRLM13Yscma8
iVOVS1y1iWLzYlGN3WRZ9gfLU60KGP5lI0A8UZ5NnTkCEfFBhgzhveusI7kt8XZl
H5iETYUm
=AWlV
-----END PGP SIGNATURE-----
commit

45157da9bf2ee40aac8ad1e5310fbe73eb0fbc3d

parent

e130b5b6df964e5cf1ddf75bd25a980ea3d1f478

4 files changed, 196 insertions(+), 27 deletions(-)

jump to
M AI.jsAI.js

@@ -18,6 +18,103 @@ self.target = target;

self.mode = mode; } +AI.incrementAttention = function() +{ + teams.cpu.units[AI.focus].attentionSpan += 1; + if (teams.cpu.units[AI.focus].attentionSpan == 7) + { + teams.cpu.units[AI.focus].attentionSpan = 0; + } +} + +AI.setTargetType = function() +{ + var x = teams.cpu.units[AI.focus]; + var w = AI.rand(2); + var z = AI.rand(5); + z = 0; + switch (z) + { + case 0: + case 1: + x.targetType = "city"; + break; + case 2: + case 3: + case 4: + if (teams.p1.units.length > 0) + { + switch (w) + { + case 0: + x.targetType = "unit" + break; + case 1: + x.targetType = "struct" + break; + } + } + else teams.cpu.units[AI.focus].targetType = "struct"; + break; + } +} + +AI.findTarget = function() +{ + var x = teams.cpu.units[AI.focus]; + switch (x.targetType) + { + case "city": + x.target = AI.findSafeCity(); + break; + case "unit": + x.target = AI.selectEnemyUnit(); + break; + case "struct": + x.target = AI.selectEnemyStruct(); + break; + } +} + +AI.findSafeCity = function() +{ + var z, i, j, k; + var tX, tY, d; + tX = -1; + tY = -1; + d = 1000; + z = teams.cpu.units[AI.focus] + + for (i = 0; i < 64; i++) + { + for (j = 0; j < 64; j++) + { + if (map.data[i][j].type == "city" && dist(map.data[i][j], z) < d) + { + for (k = 0; k < teams.cpu.structs.length; k++) + { + if (dist(map.data[i][j], teams.cpu.structs[k]) > 3) + { + tX = i; + tY = j; + } + } + } + } + } + if (tX >= 0 && tY >= 0) + return map.data[tX][tY]; + else return {}; +} + +AI.selectEnemyUnit = function() +{ +} + +AI.selectEnemyStruct = function() +{ +} + AI.getBearing = function(self, target) { var w, z, d;

@@ -91,6 +188,58 @@ }

else return u; } +AI.equip = function(u) +{ + var z; + var unit = map.data[mapCursor.x][mapCursor.y].unit; + + if (teams.cpu.energy >= 80) + { + z = AI.rand(4); + } + else if (teams.cpu.energy >= 45) + { + z = AI.rand(3); + } + else if (teams.cpu.energy >= 15) + { + z = AI.rand(2); + } + else if (teams.cpu.energy >= 12) + { + z = 0; + } + else z = -1; + + switch (z) + { + case 0: + while (teams.cpu.energy >= 12 || (!isEmptyObject(unit.equipment) && unit.equipment.grade < unit.equipment.limit)) + { + equipOrUpgradeRifleMKI(); + } + break; + case 1: + while (teams.cpu.energy >= 15 || (!isEmptyObject(unit.equipment) && unit.equipment.grade < unit.equipment.limit)) + { + equipOrUpgradeBeamSabreMKI(); + } + break; + case 2: + while (teams.cpu.energy >= 45 || (!isEmptyObject(unit.equipment) && unit.equipment.grade < unit.equipment.limit)) + { + equipOrUpgradeBeamCannon(); + } + break; + case 3: + while (teams.cpu.energy >= 80 || (!isEmptyObject(unit.equipment) && unit.equipment.grade < unit.equipment.limit)) + { + equipOrUpgradeHellBomb(); + } + break; + } +} + AI.generatePath = function(u) { movement.init(u);

@@ -233,7 +382,7 @@ for (j = origin.y; j < 64; j++)

{ if (dist(origin, map.data[i][j]) < teams.cpu.energy/15 && isEmptyObject(map.data[i][j].structure)) { - return map.data[i][j]; + console.log(i + ", " + j); return map.data[i][j]; } } }

@@ -245,7 +394,7 @@ for (j = origin.y; j >= 0; j--)

{ if (dist(origin, map.data[i][j]) < teams.cpu.energy/15 && isEmptyObject(map.data[i][j].structure)) { - return map.data[i][j]; + console.log(i + ", " + j); return map.data[i][j]; } } }

@@ -257,7 +406,7 @@ for (j = 0; j < 64; j++)

{ if (dist(origin, map.data[i][j]) < teams.cpu.energy/15 && isEmptyObject(map.data[i][j].structure)) { - return map.data[i][j]; + console.log(i + ", " + j); return map.data[i][j]; } } }

@@ -269,7 +418,7 @@ for (j = 63; j >= 0; j--)

{ if (dist(origin, map.data[i][j]) < teams.cpu.energy/15 && isEmptyObject(map.data[i][j].structure)) { - return map.data[i][j]; + console.log(i + ", " + j); return map.data[i][j]; } } }

@@ -287,6 +436,7 @@ w = AI.rand(4);

switch(w) { case 0: + console.log("rolled 0"); for (i = 0; i < 64; i++) { for (j = 0; j < 64; j++)

@@ -299,6 +449,7 @@ }

} break; case 1: + console.log("rolled 1"); for (i = 63; i >= 0; i--) { for (j = 63; j >= 0; j--)

@@ -311,6 +462,7 @@ }

} break; case 2: + console.log("rolled 2"); for (i = 63; i >= 0; i--) { for (j = 0; j < 64; j++)

@@ -323,6 +475,7 @@ }

} break; case 3: + console.log("rolled 3"); for (i = 0; i < 64; i++) { for (j = 63; j >= 0; j--)

@@ -337,27 +490,17 @@ break;

} } -AI.manageEqiupment = function() +AI.manageEquipment = function() { var i, j, k; for (i = 0; i < teams.cpu.units.length; i++) { j = map.data[teams.cpu.units[i].x][teams.cpu.units[i].y]; - if (!isEmptyObject(j.structure) && j.structure.name == "cpu armory") + if (isEmptyObject(teams.cpu.units[i].equipment) && !isEmptyObject(j.structure) && j.structure.name == "cpu armory") { mapCursor.x = j.x; mapCursor.y = j.y; - if (teams.cpu.energy >= 80) - { - k = AI.rand(4) - switch (k) - { - case 0: - case 1: - case 2: - case 3: - } - } + AI.equip(); } } }

@@ -369,9 +512,11 @@ var cell = AI.findNewStructClose();

switch (z) { case 0: + console.log("finding spot for new struct closeby"); cell = AI.findNewStructClose(); break; case 1: + console.log("finding spot for new struct farout"); cell = AI.findNewStructFar(); break; }

@@ -385,7 +530,7 @@ map.degradeCell(map.data[cell.x][cell.y]);

case "plain": if (teams.cpu.energy >= 40) { - if (teams.cpu.energy/teams.p1.energy > 2 || (teams.cpu.units.length/teams.p1.units.length <= 1.5 && AI.countStructs("cpu factory") == 0) || teams.cpu.structs.length/teams.p1.structs.length >= 1.5) + if ((teams.cpu.units.length/teams.p1.units.length <= 1.5 && AI.countStructs("cpu factory") == 0) || teams.cpu.structs.length/teams.p1.structs.length >= 1.5) { buildFactory() }
M Engine.jsEngine.js

@@ -184,9 +184,13 @@ if (isEmptyObject(teams.cpu.units[AI.focus].equipment))

{ AI.assignTarget(teams.cpu.units[AI.focus], AI.getClosestArmory(teams.cpu.units[AI.focus]), "defend"); } + else if (isEmptyObject(teams.cpu.units[AI.focus].target)) + { + AI.getPriorityTarget(teams.cpu.units[AI.focus]) + } else { - AI.assignTarget(teams.cpu.units[i], map.data[16][16]); + AI.incrementAttention(); } gameState.flow = "cpuPathGen"; }

@@ -221,6 +225,7 @@ {

if (AI.focus >= teams.cpu.units.length) { AI.focus = 0; + AI.manageEquipment(); endPhase(); } else gameState.flow = "cpuGenTargets";
M Equipment.jsEquipment.js

@@ -52,6 +52,7 @@

function equipOrUpgradeBeamSabreMKI() { var unit = map.data[mapCursor.x][mapCursor.y].unit; + var m = false; if (unit.equipment.name != "Beam Sabre mkI") { unit.equipment = beamSabreMKI();

@@ -62,15 +63,19 @@ if (unit.equipment.grade < unit.equipment.limit)

{ unit.equipment.grade++; } + else + m = true; } switch(gameState.phase) { case "p1": - teams.p1.energy -= unit.equipment.cost; + if (!m) + teams.p1.energy -= unit.equipment.cost; resetFlow(); break; case "cpu": - teams.cpu.energy -= unit.equipment.cost; + if (!m) + teams.cpu.energy -= unit.equipment.cost; break; } }

@@ -94,6 +99,7 @@

function equipOrUpgradeRifleMKI() { var unit = map.data[mapCursor.x][mapCursor.y].unit; + var m = false; if (unit.equipment.name != "Rifle mkI") { unit.equipment = rifleMKI();

@@ -104,15 +110,18 @@ if (unit.equipment.grade < unit.equipment.limit)

{ unit.equipment.grade++; } + else m = true; } switch(gameState.phase) { case "p1": - teams.p1.energy -= unit.equipment.cost; + if (!m) + teams.p1.energy -= unit.equipment.cost; resetFlow(); break; case "cpu": - teams.cpu.energy -= unit.equipment.cost; + if (!m) + teams.cpu.energy -= unit.equipment.cost; break; } }

@@ -135,6 +144,7 @@

function equipOrUpgradeBeamCannon() { var unit = map.data[mapCursor.x][mapCursor.y].unit; + var m = false; if (unit.equipment.name != "Beam Cannon") { unit.equipment = beamCannon();

@@ -145,15 +155,18 @@ if (unit.equipment.grade < unit.equipment.limit)

{ unit.equipment.grade++; } + else m = true; } switch(gameState.phase) { case "p1": - teams.p1.energy -= unit.equipment.cost; + if (!m) + teams.p1.energy -= unit.equipment.cost; resetFlow(); break; case "cpu": - teams.cpu.energy -= unit.equipment.cost; + if (!m) + teams.cpu.energy -= unit.equipment.cost; break; } }

@@ -176,6 +189,7 @@

function equipOrUpgradeHellBomb() { var unit = map.data[mapCursor.x][mapCursor.y].unit; + var m = false; if (unit.equipment.name != "Hell Bomb") { unit.equipment = hellBomb();

@@ -186,15 +200,18 @@ if (unit.equipment.grade < unit.equipment.limit)

{ unit.equipment.grade++; } + else m = true; } switch(gameState.phase) { case "p1": - teams.p1.energy -= unit.equipment.cost; + if (!m) + teams.p1.energy -= unit.equipment.cost; resetFlow(); break; case "cpu": - teams.cpu.energy -= unit.equipment.cost; + if (!m) + teams.cpu.energy -= unit.equipment.cost; break; } }
M Unit.jsUnit.js

@@ -16,7 +16,9 @@ this.name = "";

//only used for CPU units: this.target = {}; + this.targetType = ""; this.mode = ""; + this.attentionSpan = 0; } function mkAce(player, x, y)