Skip to content

Commit 8d921f4

Browse files
committed
Improve upgrading
1 parent dd12c78 commit 8d921f4

1 file changed

Lines changed: 42 additions & 39 deletions

File tree

src/core/execution/nation/NationStructureBehavior.ts

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
Player,
55
PlayerType,
66
Relation,
7+
StructureTypes,
78
Unit,
89
UnitType,
910
} from "../../game/Game";
@@ -49,7 +50,7 @@ const STRUCTURE_RATIOS: Partial<Record<UnitType, StructureRatioConfig>> = {
4950
/** Perceived cost increase percentage per city owned */
5051
const CITY_PERCEIVED_COST_INCREASE_PER_OWNED = 1;
5152

52-
/** If we have more than this many structures per this tiles, prefer upgrading over building */
53+
/** If we have more than this many total structures per 1000 tiles, prefer upgrading over building */
5354
const UPGRADE_DENSITY_THRESHOLD = 1 / 1000;
5455

5556
export class NationStructureBehavior {
@@ -87,7 +88,7 @@ export class NationStructureBehavior {
8788
}
8889
}
8990

90-
if (this.maybeSpawnCity()) {
91+
if (this.maybeSpawnStructure(UnitType.City)) {
9192
return true;
9293
}
9394

@@ -132,50 +133,15 @@ export class NationStructureBehavior {
132133
return this.game.unitInfo(type).cost(this.game, this.player);
133134
}
134135

135-
private maybeSpawnCity(): boolean {
136-
const perceivedCost = this.getPerceivedCost(UnitType.City);
137-
if (this.player.gold() < perceivedCost) {
138-
return false;
139-
}
140-
const tile = this.structureSpawnTile(UnitType.City);
141-
if (tile === null) {
142-
return false;
143-
}
144-
const canBuild = this.player.canBuild(UnitType.City, tile);
145-
if (canBuild === false) {
146-
return false;
147-
}
148-
this.game.addExecution(
149-
new ConstructionExecution(this.player, UnitType.City, tile),
150-
);
151-
return true;
152-
}
153-
154136
private maybeSpawnStructure(type: UnitType): boolean {
155137
const perceivedCost = this.getPerceivedCost(type);
156138
if (this.player.gold() < perceivedCost) {
157139
return false;
158140
}
159141

160142
// Check if we should upgrade instead of building new
161-
const existingStructures = this.player.units(type);
162-
const tilesOwned = this.player.numTilesOwned();
163-
const density = existingStructures.length / tilesOwned;
164-
165-
if (density > UPGRADE_DENSITY_THRESHOLD && existingStructures.length > 0) {
166-
// Try to upgrade an existing structure instead
167-
const structureToUpgrade =
168-
this.findBestStructureToUpgrade(existingStructures);
169-
if (
170-
structureToUpgrade !== null &&
171-
this.player.canUpgradeUnit(structureToUpgrade)
172-
) {
173-
this.game.addExecution(
174-
new UpgradeStructureExecution(this.player, structureToUpgrade.id()),
175-
);
176-
return true;
177-
}
178-
// Fall through to build new if we can't upgrade
143+
if (this.tryUpgradeInsteadOfBuilding(this.player.units(type))) {
144+
return true;
179145
}
180146

181147
const tile = this.structureSpawnTile(type);
@@ -222,6 +188,43 @@ export class NationStructureBehavior {
222188
return BigInt(Math.ceil(Number(realCost) * multiplier));
223189
}
224190

191+
/**
192+
* Tries to upgrade an existing structure if density threshold is exceeded.
193+
* @param structures The pool of structures to consider for upgrading
194+
* @returns true if an upgrade was initiated, false otherwise
195+
*/
196+
private tryUpgradeInsteadOfBuilding(structures: Unit[]): boolean {
197+
if (this.getTotalStructureDensity() <= UPGRADE_DENSITY_THRESHOLD) {
198+
return false;
199+
}
200+
if (structures.length === 0) {
201+
return false;
202+
}
203+
const structureToUpgrade = this.findBestStructureToUpgrade(structures);
204+
if (
205+
structureToUpgrade !== null &&
206+
this.player.canUpgradeUnit(structureToUpgrade)
207+
) {
208+
this.game.addExecution(
209+
new UpgradeStructureExecution(this.player, structureToUpgrade.id()),
210+
);
211+
return true;
212+
}
213+
return false;
214+
}
215+
216+
/**
217+
* Calculates total structure density across player's territory.
218+
*/
219+
private getTotalStructureDensity(): number {
220+
let totalStructures = 0;
221+
for (const type of StructureTypes) {
222+
totalStructures += this.player.unitsOwned(type);
223+
}
224+
const tilesOwned = this.player.numTilesOwned();
225+
return tilesOwned > 0 ? totalStructures / tilesOwned : 0;
226+
}
227+
225228
/**
226229
* Finds the best structure to upgrade, preferring structures protected by a SAM.
227230
*/

0 commit comments

Comments
 (0)