@supalosa/chronodivide-bot 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/.prettierrc +5 -5
  2. package/README.md +11 -3
  3. package/dist/bot/bot.js +15 -7
  4. package/dist/bot/bot.js.map +1 -0
  5. package/dist/bot/logic/awareness.js +12 -2
  6. package/dist/bot/logic/awareness.js.map +1 -0
  7. package/dist/bot/logic/awarenessImpl.js +132 -0
  8. package/dist/bot/logic/awarenessImpl.js.map +1 -0
  9. package/dist/bot/logic/building/ArtilleryUnit.js +1 -0
  10. package/dist/bot/logic/building/ArtilleryUnit.js.map +1 -0
  11. package/dist/bot/logic/building/antiGroundStaticDefence.js +1 -0
  12. package/dist/bot/logic/building/antiGroundStaticDefence.js.map +1 -0
  13. package/dist/bot/logic/building/basicAirUnit.js +1 -0
  14. package/dist/bot/logic/building/basicAirUnit.js.map +1 -0
  15. package/dist/bot/logic/building/basicBuilding.js +1 -0
  16. package/dist/bot/logic/building/basicBuilding.js.map +1 -0
  17. package/dist/bot/logic/building/basicGroundUnit.js +1 -0
  18. package/dist/bot/logic/building/basicGroundUnit.js.map +1 -0
  19. package/dist/bot/logic/building/building.js +57 -11
  20. package/dist/bot/logic/building/building.js.map +1 -0
  21. package/dist/bot/logic/building/harvester.js +1 -0
  22. package/dist/bot/logic/building/harvester.js.map +1 -0
  23. package/dist/bot/logic/building/powerPlant.js +1 -0
  24. package/dist/bot/logic/building/powerPlant.js.map +1 -0
  25. package/dist/bot/logic/building/queueController.js +1 -0
  26. package/dist/bot/logic/building/queueController.js.map +1 -0
  27. package/dist/bot/logic/building/resourceCollectionBuilding.js +1 -0
  28. package/dist/bot/logic/building/resourceCollectionBuilding.js.map +1 -0
  29. package/dist/bot/logic/common/scout.js +100 -0
  30. package/dist/bot/logic/common/scout.js.map +1 -0
  31. package/dist/bot/logic/common/utils.js +2 -0
  32. package/dist/bot/logic/common/utils.js.map +1 -0
  33. package/dist/bot/logic/map/map.js +9 -25
  34. package/dist/bot/logic/map/map.js.map +1 -0
  35. package/dist/bot/logic/map/sector.js +33 -1
  36. package/dist/bot/logic/map/sector.js.map +1 -0
  37. package/dist/bot/logic/mission/mission.js +3 -1
  38. package/dist/bot/logic/mission/mission.js.map +1 -0
  39. package/dist/bot/logic/mission/missionController.js +5 -4
  40. package/dist/bot/logic/mission/missionController.js.map +1 -0
  41. package/dist/bot/logic/mission/missionFactories.js +1 -0
  42. package/dist/bot/logic/mission/missionFactories.js.map +1 -0
  43. package/dist/bot/logic/mission/missions/attackMission.js +7 -8
  44. package/dist/bot/logic/mission/missions/attackMission.js.map +1 -0
  45. package/dist/bot/logic/mission/missions/defenceMission.js +12 -7
  46. package/dist/bot/logic/mission/missions/defenceMission.js.map +1 -0
  47. package/dist/bot/logic/mission/missions/expansionMission.js +5 -4
  48. package/dist/bot/logic/mission/missions/expansionMission.js.map +1 -0
  49. package/dist/bot/logic/mission/missions/oneTimeMission.js +3 -2
  50. package/dist/bot/logic/mission/missions/oneTimeMission.js.map +1 -0
  51. package/dist/bot/logic/mission/missions/retreatMission.js +3 -2
  52. package/dist/bot/logic/mission/missions/retreatMission.js.map +1 -0
  53. package/dist/bot/logic/mission/missions/scoutingMission.js +8 -9
  54. package/dist/bot/logic/mission/missions/scoutingMission.js.map +1 -0
  55. package/dist/bot/logic/squad/behaviours/attackSquad.js +63 -56
  56. package/dist/bot/logic/squad/behaviours/combatSquad.js +6 -3
  57. package/dist/bot/logic/squad/behaviours/combatSquad.js.map +1 -0
  58. package/dist/bot/logic/squad/behaviours/common.js +7 -4
  59. package/dist/bot/logic/squad/behaviours/common.js.map +1 -0
  60. package/dist/bot/logic/squad/behaviours/defenceSquad.js +15 -2
  61. package/dist/bot/logic/squad/behaviours/expansionSquad.js +1 -0
  62. package/dist/bot/logic/squad/behaviours/expansionSquad.js.map +1 -0
  63. package/dist/bot/logic/squad/behaviours/retreatSquad.js +6 -10
  64. package/dist/bot/logic/squad/behaviours/retreatSquad.js.map +1 -0
  65. package/dist/bot/logic/squad/behaviours/scoutingSquad.js +66 -18
  66. package/dist/bot/logic/squad/behaviours/scoutingSquad.js.map +1 -0
  67. package/dist/bot/logic/squad/squad.js +3 -3
  68. package/dist/bot/logic/squad/squad.js.map +1 -0
  69. package/dist/bot/logic/squad/squadBehaviour.js +1 -0
  70. package/dist/bot/logic/squad/squadBehaviour.js.map +1 -0
  71. package/dist/bot/logic/squad/squadBehaviours.js +1 -0
  72. package/dist/bot/logic/squad/squadBehaviours.js.map +1 -0
  73. package/dist/bot/logic/squad/squadController.js +73 -23
  74. package/dist/bot/logic/squad/squadController.js.map +1 -0
  75. package/dist/bot/logic/threat/threat.js +1 -0
  76. package/dist/bot/logic/threat/threat.js.map +1 -0
  77. package/dist/bot/logic/threat/threatCalculator.js +1 -0
  78. package/dist/bot/logic/threat/threatCalculator.js.map +1 -0
  79. package/dist/exampleBot.js +24 -7
  80. package/dist/exampleBot.js.map +1 -0
  81. package/package.json +9 -6
  82. package/src/bot/bot.ts +17 -11
  83. package/src/bot/logic/awareness.ts +22 -5
  84. package/src/bot/logic/building/ArtilleryUnit.ts +43 -43
  85. package/src/bot/logic/building/antiGroundStaticDefence.ts +60 -60
  86. package/src/bot/logic/building/basicAirUnit.ts +68 -68
  87. package/src/bot/logic/building/basicBuilding.ts +47 -47
  88. package/src/bot/logic/building/building.ts +72 -12
  89. package/src/bot/logic/building/powerPlant.ts +32 -32
  90. package/src/bot/logic/building/resourceCollectionBuilding.ts +56 -56
  91. package/src/bot/logic/common/scout.ts +127 -1
  92. package/src/bot/logic/common/utils.ts +1 -0
  93. package/src/bot/logic/map/map.ts +70 -84
  94. package/src/bot/logic/map/sector.ts +46 -4
  95. package/src/bot/logic/mission/mission.ts +2 -2
  96. package/src/bot/logic/mission/missionController.ts +7 -6
  97. package/src/bot/logic/mission/missionFactories.ts +3 -0
  98. package/src/bot/logic/mission/missions/attackMission.ts +19 -13
  99. package/src/bot/logic/mission/missions/defenceMission.ts +35 -15
  100. package/src/bot/logic/mission/missions/expansionMission.ts +6 -4
  101. package/src/bot/logic/mission/missions/oneTimeMission.ts +3 -2
  102. package/src/bot/logic/mission/missions/retreatMission.ts +3 -2
  103. package/src/bot/logic/mission/missions/scoutingMission.ts +9 -6
  104. package/src/bot/logic/squad/behaviours/combatSquad.ts +6 -2
  105. package/src/bot/logic/squad/behaviours/common.ts +6 -4
  106. package/src/bot/logic/squad/behaviours/retreatSquad.ts +10 -12
  107. package/src/bot/logic/squad/behaviours/scoutingSquad.ts +81 -23
  108. package/src/bot/logic/squad/squad.ts +3 -2
  109. package/src/bot/logic/squad/squadBehaviour.ts +3 -1
  110. package/src/bot/logic/squad/squadController.ts +136 -69
  111. package/src/bot/logic/threat/threat.ts +15 -15
  112. package/src/bot/logic/threat/threatCalculator.ts +99 -99
  113. package/src/exampleBot.ts +25 -6
  114. package/tsconfig.json +73 -73
  115. package/dist/bot/logic/building/massedAntiGroundUnit.js +0 -20
  116. package/dist/bot/logic/building/queues.js +0 -19
  117. package/dist/bot/logic/knowledge.js +0 -1
  118. package/dist/bot/logic/mission/basicMission.js +0 -26
  119. package/dist/bot/logic/mission/expansionMission.js +0 -32
  120. package/dist/bot/logic/squad/behaviours/squadExpansion.js +0 -31
  121. package/dist/bot/logic/squad/behaviours/squadScouters.js +0 -8
@@ -1,12 +1,14 @@
1
1
  // Meta-controller for forming and controlling squads.
2
2
  import { SquadLiveness } from "./squad.js";
3
3
  import { getDistanceBetween } from "../map/map.js";
4
+ import _ from "lodash";
4
5
  export class SquadController {
5
- constructor() {
6
+ constructor(logger) {
7
+ this.logger = logger;
6
8
  this.squads = [];
7
9
  this.unitIdToSquad = new Map();
8
10
  }
9
- onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, logger) {
11
+ onAiUpdate(gameApi, actionsApi, playerData, matchAwareness) {
10
12
  // Remove dead squads or those where the mission is dead.
11
13
  this.squads = this.squads.filter((squad) => squad.getLiveness() !== SquadLiveness.SquadDead);
12
14
  this.squads.sort((a, b) => a.getName().localeCompare(b.getName()));
@@ -15,7 +17,7 @@ export class SquadController {
15
17
  this.squads.forEach((squad) => {
16
18
  squad.getUnitIds().forEach((unitId) => {
17
19
  if (this.unitIdToSquad.has(unitId)) {
18
- logger(`WARNING: unit ${unitId} is in multiple squads, please debug.`);
20
+ this.logger(`WARNING: unit ${unitId} is in multiple squads, please debug.`);
19
21
  }
20
22
  else {
21
23
  this.unitIdToSquad.set(unitId, squad);
@@ -25,7 +27,7 @@ export class SquadController {
25
27
  const squadActions = this.squads.map((squad) => {
26
28
  return {
27
29
  squad,
28
- action: squad.onAiUpdate(gameApi, actionsApi, playerData, matchAwareness),
30
+ action: squad.onAiUpdate(gameApi, actionsApi, playerData, matchAwareness, this.logger),
29
31
  };
30
32
  });
31
33
  // Handle disbands and merges.
@@ -35,7 +37,7 @@ export class SquadController {
35
37
  squadActions
36
38
  .filter((a) => isDisband(a.action))
37
39
  .forEach((a) => {
38
- logger(`Squad ${a.squad.getName()} disbanding as requested.`);
40
+ this.logger(`Squad ${a.squad.getName()} disbanding as requested.`);
39
41
  a.squad.getMission()?.removeSquad();
40
42
  a.squad.getUnitIds().forEach((unitId) => {
41
43
  this.unitIdToSquad.delete(unitId);
@@ -47,7 +49,7 @@ export class SquadController {
47
49
  .forEach((a) => {
48
50
  let mergeInto = a.action;
49
51
  if (disbandedSquads.has(mergeInto.mergeInto.getName())) {
50
- logger(`Squad ${a.squad.getName()} tried to merge into disbanded squad ${mergeInto.mergeInto.getName()}, cancelling.`);
52
+ this.logger(`Squad ${a.squad.getName()} tried to merge into disbanded squad ${mergeInto.mergeInto.getName()}, cancelling.`);
51
53
  return;
52
54
  }
53
55
  a.squad.getUnitIds().forEach((unitId) => mergeInto.mergeInto.addUnit(unitId));
@@ -74,19 +76,37 @@ export class SquadController {
74
76
  });
75
77
  return prev;
76
78
  }, {});
77
- Object.entries(unitIdToHighestRequest).forEach(([id, request]) => {
79
+ // Map of Squad ID to Unit Type to Count.
80
+ const newSquadAssignments = Object.entries(unitIdToHighestRequest)
81
+ .flatMap(([id, request]) => {
78
82
  const unitId = Number.parseInt(id);
79
83
  const unit = gameApi.getUnitData(unitId);
80
84
  const { squad: requestingSquad } = request;
81
85
  const missionName = requestingSquad.getMission()?.getUniqueName();
82
86
  if (!unit) {
83
- logger(`mission ${missionName} requested non-existent unit ${unitId}`);
84
- return;
87
+ this.logger(`mission ${missionName} requested non-existent unit ${unitId}`);
88
+ return [];
85
89
  }
86
90
  if (!this.unitIdToSquad.has(unitId)) {
87
- logger(`granting specific unit ${unitId} to squad ${requestingSquad.getName()} in mission ${missionName}`);
88
91
  this.addUnitToSquad(requestingSquad, unit);
92
+ return [{ unitName: unit?.name, squad: requestingSquad.getName() }];
93
+ }
94
+ return [];
95
+ })
96
+ .reduce((acc, curr) => {
97
+ if (!acc[curr.squad]) {
98
+ acc[curr.squad] = {};
89
99
  }
100
+ if (!acc[curr.squad][curr.unitName]) {
101
+ acc[curr.squad][curr.unitName] = 0;
102
+ }
103
+ acc[curr.squad][curr.unitName] = acc[curr.squad][curr.unitName] + 1;
104
+ return acc;
105
+ }, {});
106
+ Object.entries(newSquadAssignments).forEach(([squad, assignments]) => {
107
+ this.logger(`Squad ${squad} received: ${Object.entries(assignments)
108
+ .map(([unitType, count]) => unitType + " x " + count)
109
+ .join(", ")}`);
90
110
  });
91
111
  // Request units by type
92
112
  const isRequest = (a) => a.type === "request";
@@ -116,27 +136,48 @@ export class SquadController {
116
136
  .map((unitId) => gameApi.getUnitData(unitId))
117
137
  .filter((unit) => !!unit && !this.unitIdToSquad.has(unit.id || 0))
118
138
  .map((unit) => unit);
119
- freeUnits.forEach((freeUnit) => {
139
+ // [squadName][unitName]['type' | 'grab']
140
+ const newAssignmentsByType = freeUnits
141
+ .flatMap((freeUnit) => {
120
142
  if (unitTypeToHighestRequest.hasOwnProperty(freeUnit.name)) {
121
143
  const { squad: requestingSquad } = unitTypeToHighestRequest[freeUnit.name];
122
- logger(`granting unit ${freeUnit.id}#${freeUnit.name} to squad ${requestingSquad.getName()}`);
144
+ this.logger(`granting unit ${freeUnit.id}#${freeUnit.name} to squad ${requestingSquad.getName()}`);
123
145
  this.addUnitToSquad(requestingSquad, freeUnit);
124
146
  delete unitTypeToHighestRequest[freeUnit.name];
147
+ return [
148
+ { unitName: freeUnit.name, squad: requestingSquad.getName(), method: "type" },
149
+ ];
125
150
  }
126
151
  else if (grabRequests.length > 0) {
127
- grabRequests.some((request) => {
128
- const { squad: requestingSquad } = request;
129
- if (freeUnit.rules.isSelectableCombatant &&
130
- getDistanceBetween(freeUnit, request.action.point) <= request.action.radius) {
131
- logger(`granting unit ${freeUnit.id}#${freeUnit.name} to squad ${requestingSquad.getName()} via grab at ${request.action.point.x},${request.action.point.y}`);
132
- this.addUnitToSquad(requestingSquad, freeUnit);
133
- return true;
134
- }
135
- else {
136
- return false;
137
- }
152
+ const grantedSquad = grabRequests.find((request) => {
153
+ return (freeUnit.rules.isSelectableCombatant &&
154
+ getDistanceBetween(freeUnit, request.action.point) <= request.action.radius);
138
155
  });
156
+ if (grantedSquad) {
157
+ this.addUnitToSquad(grantedSquad.squad, freeUnit);
158
+ return [
159
+ { unitName: freeUnit.name, squad: grantedSquad.squad.getName(), method: "grab" },
160
+ ];
161
+ }
139
162
  }
163
+ return [];
164
+ })
165
+ .reduce((acc, curr) => {
166
+ if (!acc[curr.squad]) {
167
+ acc[curr.squad] = {};
168
+ }
169
+ if (!acc[curr.squad][curr.unitName]) {
170
+ acc[curr.squad][curr.unitName] = { grab: 0, type: 0 };
171
+ }
172
+ acc[curr.squad][curr.unitName][curr.method] = acc[curr.squad][curr.unitName][curr.method] + 1;
173
+ return acc;
174
+ }, {});
175
+ Object.entries(newAssignmentsByType).forEach(([squad, assignments]) => {
176
+ this.logger(`Squad ${squad} received: ${Object.entries(assignments)
177
+ .flatMap(([unitType, methodToCount]) => Object.entries(methodToCount)
178
+ .filter(([, count]) => count > 0)
179
+ .map(([method, count]) => unitType + " x " + count + " (by " + method + ")"))
180
+ .join(", ")}`);
140
181
  });
141
182
  }
142
183
  addUnitToSquad(squad, unit) {
@@ -146,4 +187,13 @@ export class SquadController {
146
187
  registerSquad(squad) {
147
188
  this.squads.push(squad);
148
189
  }
190
+ debugSquads(gameApi) {
191
+ const unitsInSquad = (unitIds) => _.countBy(unitIds, (unitId) => gameApi.getUnitData(unitId)?.name);
192
+ this.squads.forEach((squad) => {
193
+ this.logger(`Squad ${squad.getName()}: ${Object.entries(unitsInSquad(squad.getUnitIds()))
194
+ .map(([unitName, count]) => `${unitName} x ${count}`)
195
+ .join(", ")}`);
196
+ });
197
+ }
149
198
  }
199
+ //# sourceMappingURL=squadController.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"squadController.js","sourceRoot":"","sources":["../../../../src/bot/logic/squad/squadController.ts"],"names":[],"mappings":"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"}
@@ -20,3 +20,4 @@ export class GlobalThreat {
20
20
  this.totalAvailableAirPower = totalAvailableAirPower;
21
21
  }
22
22
  }
23
+ //# sourceMappingURL=threat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threat.js","sourceRoot":"","sources":["../../../../src/bot/logic/threat/threat.ts"],"names":[],"mappings":"AAAA,gGAAgG;AAEhG,MAAM,OAAO,YAAY;IACrB,YACW,SAAiB,EAAE,4DAA4D;IAC/E,wBAAgC,EAAE,+EAA+E;IACjH,uBAA+B,EAAE,6EAA6E;IAC9G,2BAAmC,EAAE,6EAA6E;IAClH,oBAA4B,EAAE,0EAA0E;IACxG,mBAA2B,EAAE,+DAA+D;IAC5F,iCAAyC,EAAE,qCAAqC;IAChF,8BAAsC,EAAE,kCAAkC;IAC1E,sBAA8B;QAR9B,cAAS,GAAT,SAAS,CAAQ;QACjB,6BAAwB,GAAxB,wBAAwB,CAAQ;QAChC,4BAAuB,GAAvB,uBAAuB,CAAQ;QAC/B,gCAA2B,GAA3B,2BAA2B,CAAQ;QACnC,yBAAoB,GAApB,oBAAoB,CAAQ;QAC5B,wBAAmB,GAAnB,mBAAmB,CAAQ;QAC3B,sCAAiC,GAAjC,iCAAiC,CAAQ;QACzC,mCAA8B,GAA9B,8BAA8B,CAAQ;QACtC,2BAAsB,GAAtB,sBAAsB,CAAQ;IACtC,CAAC;CACP"}
@@ -70,3 +70,4 @@ function calculateFirepowerForUnits(game, unitIds) {
70
70
  });
71
71
  return threat;
72
72
  }
73
+ //# sourceMappingURL=threatCalculator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"threatCalculator.js","sourceRoot":"","sources":["../../../../src/bot/logic/threat/threatCalculator.ts"],"names":[],"mappings":"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"}
@@ -22,14 +22,30 @@ async function main() {
22
22
  await cdapi.init(process.env.MIX_DIR || "./");
23
23
  console.log("Server URL: " + process.env.SERVER_URL);
24
24
  console.log("Client URL: " + process.env.CLIENT_URL);
25
- const game = await cdapi.createGame({
26
- // Uncomment the following lines to play in real time versus the bot
27
- /*online: true,
28
- serverUrl: process.env.SERVER_URL!,
29
- clientUrl: process.env.CLIENT_URL!,
30
- agents: [new SupalosaBot(botName, "Americans"), { name: otherBotName, country: "French" }],*/
25
+ /*
26
+ Countries:
27
+ 0=Americans
28
+ 1=Alliance -> Korea
29
+ 2=French
30
+ 3=Germans
31
+ 4=British
32
+
33
+ 5=Africans -> Libya
34
+ 6=Arabs -> Iraq
35
+ 7=Confederation -> Cuba
36
+ 8=Russians
37
+ */
38
+ const onlineSettings = {
39
+ online: true,
40
+ serverUrl: process.env.SERVER_URL,
41
+ clientUrl: process.env.CLIENT_URL,
42
+ agents: [new SupalosaBot(botName, "Americans"), { name: otherBotName, country: "French" }],
43
+ };
44
+ const offlineSettings = {
31
45
  agents: [new SupalosaBot(botName, "French", false), new SupalosaBot(otherBotName, "French", true)],
32
- //agents: [new SupalosaBot(botName, "Americans", false), new SupalosaBot(otherBotName, "Russians", false)],
46
+ };
47
+ const game = await cdapi.createGame({
48
+ ...offlineSettings,
33
49
  buildOffAlly: false,
34
50
  cratesAppear: false,
35
51
  credits: 10000,
@@ -51,3 +67,4 @@ main().catch((e) => {
51
67
  console.error(e);
52
68
  process.exit(1);
53
69
  });
70
+ //# sourceMappingURL=exampleBot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exampleBot.js","sourceRoot":"","sources":["../src/exampleBot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,KAAK,UAAU,IAAI;IACf;;;;;;;;;;;;;MAaE;IACF,MAAM,OAAO,GAAG,YAAY,CAAC;IAC7B,0CAA0C;IAC1C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/D,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;IAE9C,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,UAAW,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,UAAW,CAAC,CAAC;IAEtD;;;;;;;;;;;;MAYE;IAEF,MAAM,cAAc,GAAG;QACnB,MAAM,EAAE,IAAY;QACpB,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAW;QAClC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,UAAW;QAClC,MAAM,EAAE,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAsB;KAClH,CAAC;IAEF,MAAM,eAAe,GAAG;QACpB,MAAM,EAAE,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,IAAI,WAAW,CAAC,YAAY,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;KACrG,CAAC;IAEF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,UAAU,CAAC;QAChC,GAAG,eAAe;QAClB,YAAY,EAAE,KAAK;QACnB,YAAY,EAAE,KAAK;QACnB,OAAO,EAAE,KAAK;QACd,QAAQ,EAAE,KAAK,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACjD,SAAS,EAAE,CAAC;QACZ,OAAO;QACP,UAAU,EAAE,IAAI;QAChB,SAAS,EAAE,IAAI;QACf,YAAY,EAAE,KAAK;QACnB,SAAS,EAAE,CAAC;KACf,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE;QACvB,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC;KACvB;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;IAClB,IAAI,CAAC,OAAO,EAAE,CAAC;AACnB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;IACf,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACjB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supalosa/chronodivide-bot",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "Example bot for Chrono Divide",
5
5
  "repository": "https://github.com/Supalosa/supalosa-chronodivide-bot",
6
6
  "main": "dist/exampleBot.js",
@@ -13,17 +13,20 @@
13
13
  },
14
14
  "license": "UNLICENSED",
15
15
  "devDependencies": {
16
- "@timohausmann/quadtree-ts": "^2.0.0-beta.1",
17
16
  "@types/node": "^14.17.32",
18
17
  "prettier": "3.0.3",
19
- "typescript": "^4.3.5"
18
+ "typescript": "^4.3.5",
19
+ "@chronodivide/game-api": "^0.45.0"
20
+ },
21
+ "peerDependencies": {
22
+ "@chronodivide/game-api": "^0.45.0"
20
23
  },
21
24
  "dependencies": {
22
- "@chronodivide/game-api": "^0.45.0",
25
+ "@datastructures-js/priority-queue": "^6.3.0",
26
+ "@timohausmann/quadtree-ts": "^2.0.0-beta.1",
23
27
  "@types/lodash": "^4.14.199",
24
28
  "@types/luxon": "^3.3.2",
25
29
  "lodash": "^4.17.21",
26
- "luxon": "^3.4.3",
27
- "priority-queue-typescript": "^1.0.1"
30
+ "luxon": "^3.4.3"
28
31
  }
29
32
  }
package/src/bot/bot.ts CHANGED
@@ -17,9 +17,11 @@ import { SectorCache } from "./logic/map/sector.js";
17
17
  import { MissionController } from "./logic/mission/missionController.js";
18
18
  import { SquadController } from "./logic/squad/squadController.js";
19
19
  import { QUEUES, QueueController, queueTypeToName } from "./logic/building/queueController.js";
20
- import { MatchAwareness as MatchAwareness, MatchAwarenessImpl } from "./logic/awareness.js";
20
+ import { MatchAwareness, MatchAwarenessImpl } from "./logic/awareness.js";
21
21
 
22
22
  const DEBUG_TIMESTAMP_OUTPUT_INTERVAL_SECONDS = 60;
23
+
24
+ // Number of ticks per second at the base speed.
23
25
  const NATURAL_TICK_RATE = 15;
24
26
  const BOT_AUTO_SURRENDER_TIME_SECONDS = 7200; // 7200; // 2 hours (approx 30 mins in real game)
25
27
 
@@ -37,8 +39,8 @@ export class SupalosaBot extends Bot {
37
39
 
38
40
  constructor(name: string, country: string, enableLogging = true) {
39
41
  super(name, country);
40
- this.missionController = new MissionController((message) => this.logBotStatus(message));
41
- this.squadController = new SquadController();
42
+ this.missionController = new MissionController((message, sayInGame) => this.logBotStatus(message, sayInGame));
43
+ this.squadController = new SquadController((message, sayInGame) => this.logBotStatus(message, sayInGame));
42
44
  this.queueController = new QueueController();
43
45
  this.enableLogging = enableLogging;
44
46
  }
@@ -50,13 +52,15 @@ export class SupalosaBot extends Bot {
50
52
  this.tickRatio = Math.ceil(gameRate / botRate);
51
53
 
52
54
  this.knownMapBounds = determineMapBounds(game.mapApi);
55
+ const myPlayer = game.getPlayerData(this.name);
53
56
 
54
57
  this.matchAwareness = new MatchAwarenessImpl(
55
58
  null,
56
59
  new SectorCache(game.mapApi, this.knownMapBounds),
57
- game.getPlayerData(this.name).startLocation,
58
- (msg) => this.logBotStatus(msg),
60
+ myPlayer.startLocation,
61
+ (message, sayInGame) => this.logBotStatus(message, sayInGame),
59
62
  );
63
+ this.matchAwareness.onGameStart(game, myPlayer);
60
64
 
61
65
  this.logBotStatus(`Map bounds: ${this.knownMapBounds.x}, ${this.knownMapBounds.y}`);
62
66
  }
@@ -116,9 +120,7 @@ export class SupalosaBot extends Bot {
116
120
 
117
121
  // Squad logic every 3 ticks
118
122
  if (this.gameApi.getCurrentTick() % 3 === 0) {
119
- this.squadController.onAiUpdate(game, this.actionsApi, myPlayer, this.matchAwareness, (message) =>
120
- this.logBotStatus(message),
121
- );
123
+ this.squadController.onAiUpdate(game, this.actionsApi, myPlayer, this.matchAwareness);
122
124
  }
123
125
  }
124
126
  }
@@ -127,11 +129,15 @@ export class SupalosaBot extends Bot {
127
129
  return Duration.fromMillis((game.getCurrentTick() / NATURAL_TICK_RATE) * 1000).toFormat("hh:mm:ss");
128
130
  }
129
131
 
130
- private logBotStatus(message: string) {
132
+ private logBotStatus(message: string, sayInGame: boolean = false) {
131
133
  if (!this.enableLogging) {
132
134
  return;
133
135
  }
134
- console.log(`[${this.getHumanTimestamp(this.gameApi)} ${this.name}] ${message}`);
136
+ const timestamp = this.getHumanTimestamp(this.gameApi);
137
+ console.log(`[${timestamp} ${this.name}] ${message}`);
138
+ if (sayInGame) {
139
+ this.actionsApi.sayAll(`${timestamp}: ${message}`);
140
+ }
135
141
  }
136
142
 
137
143
  private logDebugState(game: GameApi) {
@@ -157,9 +163,9 @@ export class SupalosaBot extends Bot {
157
163
  this.logBotStatus(`----- Cash: ${myPlayer.credits} ----- | Queues: ${queueState}`);
158
164
  const harvesters = game.getVisibleUnits(this.name, "self", (r) => r.harvester).length;
159
165
  this.logBotStatus(`Harvesters: ${harvesters}`);
166
+ this.squadController.debugSquads(this.gameApi);
160
167
  this.logBotStatus(`----- End -----`);
161
168
  this.missionController.logDebugOutput();
162
- this.actionsApi.sayAll(`Cash: ${myPlayer.credits}`);
163
169
  }
164
170
 
165
171
  override onGameEvent(ev: ApiEvent) {
@@ -1,9 +1,12 @@
1
1
  import { GameApi, ObjectType, PlayerData, Point2D, UnitData } from "@chronodivide/game-api";
2
2
  import { SectorCache } from "./map/sector";
3
3
  import { GlobalThreat } from "./threat/threat";
4
- import { calculateGlobalThreat } from "../logic/threat/threatCalculator.js";
5
- import { determineMapBounds, getDistanceBetweenPoints, getPointTowardsOtherPoint } from "../logic/map/map.js";
6
- import { Circle, Quadtree, Rectangle } from "@timohausmann/quadtree-ts";
4
+ import { calculateGlobalThreat } from "./threat/threatCalculator.js";
5
+ import { determineMapBounds, getDistanceBetweenPoints, getPointTowardsOtherPoint } from "./map/map.js";
6
+ import { Circle, Quadtree } from "@timohausmann/quadtree-ts";
7
+ import { ScoutingManager } from "./common/scout.js";
8
+
9
+ export type UnitPositionQuery = { x: number; y: number; unitId: number };
7
10
 
8
11
  /**
9
12
  * The bot's understanding of the current state of the game.
@@ -31,6 +34,8 @@ export interface MatchAwareness {
31
34
  */
32
35
  getMainRallyPoint(): Point2D;
33
36
 
37
+ onGameStart(gameApi: GameApi, playerData: PlayerData): void;
38
+
34
39
  /**
35
40
  * Update the internal state of the Ai.
36
41
  * @param gameApi
@@ -42,6 +47,8 @@ export interface MatchAwareness {
42
47
  * True if the AI should initiate an attack.
43
48
  */
44
49
  shouldAttack(): boolean;
50
+
51
+ getScoutingManager(): ScoutingManager;
45
52
  }
46
53
 
47
54
  const SECTORS_TO_UPDATE_PER_CYCLE = 8;
@@ -51,7 +58,6 @@ const RALLY_POINT_UPDATE_INTERVAL_TICKS = 60;
51
58
  const THREAT_UPDATE_INTERVAL_TICKS = 30;
52
59
 
53
60
  type QTUnit = Circle<number>;
54
- export type UnitPositionQuery = { x: number; y: number; unitId: number };
55
61
 
56
62
  const rebuildQuadtree = (quadtree: Quadtree<QTUnit>, units: UnitData[]) => {
57
63
  quadtree.clear();
@@ -64,15 +70,17 @@ export class MatchAwarenessImpl implements MatchAwareness {
64
70
  private _shouldAttack: boolean = false;
65
71
 
66
72
  private hostileQuadTree: Quadtree<QTUnit>;
73
+ private scoutingManager: ScoutingManager;
67
74
 
68
75
  constructor(
69
76
  private threatCache: GlobalThreat | null,
70
77
  private sectorCache: SectorCache,
71
78
  private mainRallyPoint: Point2D,
72
- private logger: (message: string) => void,
79
+ private logger: (message: string, sayInGame?: boolean) => void,
73
80
  ) {
74
81
  const { x: width, y: height } = sectorCache.getMapBounds();
75
82
  this.hostileQuadTree = new Quadtree({ width, height });
83
+ this.scoutingManager = new ScoutingManager(logger);
76
84
  }
77
85
 
78
86
  getHostilesNearPoint2d(point: Point2D, radius: number): UnitPositionQuery[] {
@@ -96,6 +104,9 @@ export class MatchAwarenessImpl implements MatchAwareness {
96
104
  getMainRallyPoint(): Point2D {
97
105
  return this.mainRallyPoint;
98
106
  }
107
+ getScoutingManager(): ScoutingManager {
108
+ return this.scoutingManager;
109
+ }
99
110
 
100
111
  shouldAttack(): boolean {
101
112
  return this._shouldAttack;
@@ -121,11 +132,17 @@ export class MatchAwarenessImpl implements MatchAwareness {
121
132
  return hostilePlayerNames.includes(unit.owner);
122
133
  }
123
134
 
135
+ public onGameStart(gameApi: GameApi, playerData: PlayerData) {
136
+ this.scoutingManager.onGameStart(gameApi, playerData, this.sectorCache);
137
+ }
138
+
124
139
  onAiUpdate(game: GameApi, playerData: PlayerData): void {
125
140
  const sectorCache = this.sectorCache;
126
141
 
127
142
  sectorCache.updateSectors(game.getCurrentTick(), SECTORS_TO_UPDATE_PER_CYCLE, game.mapApi, playerData);
128
143
 
144
+ this.scoutingManager.onAiUpdate(game, playerData);
145
+
129
146
  let updateRatio = sectorCache?.getSectorUpdateRatio(game.getCurrentTick() - game.getTickRate() * 60);
130
147
  if (updateRatio && updateRatio < 1.0) {
131
148
  this.logger(`${updateRatio * 100.0}% of sectors updated in last 60 seconds.`);
@@ -1,43 +1,43 @@
1
- import { GameApi, PlayerData, TechnoRules } from "@chronodivide/game-api";
2
- import { GlobalThreat } from "../threat/threat.js";
3
- import { AiBuildingRules, getDefaultPlacementLocation, numBuildingsOwnedOfType } from "./building.js";
4
-
5
- export class ArtilleryUnit implements AiBuildingRules {
6
- constructor(private basePriority: number, private baseAmount: number) {}
7
-
8
- getPlacementLocation(
9
- game: GameApi,
10
- playerData: PlayerData,
11
- technoRules: TechnoRules
12
- ): { rx: number; ry: number } | undefined {
13
- return undefined;
14
- }
15
-
16
- getPriority(
17
- game: GameApi,
18
- playerData: PlayerData,
19
- technoRules: TechnoRules,
20
- threatCache: GlobalThreat | null
21
- ): number {
22
- // If the enemy's defensive power is increasing we will start to build these.
23
- if (threatCache) {
24
- if (threatCache.totalDefensivePower > threatCache.totalAvailableAntiGroundFirepower) {
25
- return (
26
- this.basePriority *
27
- (threatCache.totalAvailableAntiGroundFirepower / Math.max(1, threatCache.totalDefensivePower))
28
- );
29
- }
30
- }
31
- const numOwned = numBuildingsOwnedOfType(game, playerData, technoRules);
32
- return this.basePriority * (1.0 - numOwned / this.baseAmount);
33
- }
34
-
35
- getMaxCount(
36
- game: GameApi,
37
- playerData: PlayerData,
38
- technoRules: TechnoRules,
39
- threatCache: GlobalThreat | null
40
- ): number | null {
41
- return null;
42
- }
43
- }
1
+ import { GameApi, PlayerData, TechnoRules } from "@chronodivide/game-api";
2
+ import { GlobalThreat } from "../threat/threat.js";
3
+ import { AiBuildingRules, getDefaultPlacementLocation, numBuildingsOwnedOfType } from "./building.js";
4
+
5
+ export class ArtilleryUnit implements AiBuildingRules {
6
+ constructor(private basePriority: number, private baseAmount: number) {}
7
+
8
+ getPlacementLocation(
9
+ game: GameApi,
10
+ playerData: PlayerData,
11
+ technoRules: TechnoRules
12
+ ): { rx: number; ry: number } | undefined {
13
+ return undefined;
14
+ }
15
+
16
+ getPriority(
17
+ game: GameApi,
18
+ playerData: PlayerData,
19
+ technoRules: TechnoRules,
20
+ threatCache: GlobalThreat | null
21
+ ): number {
22
+ // If the enemy's defensive power is increasing we will start to build these.
23
+ if (threatCache) {
24
+ if (threatCache.totalDefensivePower > threatCache.totalAvailableAntiGroundFirepower) {
25
+ return (
26
+ this.basePriority *
27
+ (threatCache.totalAvailableAntiGroundFirepower / Math.max(1, threatCache.totalDefensivePower))
28
+ );
29
+ }
30
+ }
31
+ const numOwned = numBuildingsOwnedOfType(game, playerData, technoRules);
32
+ return this.basePriority * (1.0 - numOwned / this.baseAmount);
33
+ }
34
+
35
+ getMaxCount(
36
+ game: GameApi,
37
+ playerData: PlayerData,
38
+ technoRules: TechnoRules,
39
+ threatCache: GlobalThreat | null
40
+ ): number | null {
41
+ return null;
42
+ }
43
+ }