diff --git a/src/core/execution/NationExecution.ts b/src/core/execution/NationExecution.ts index 4a836eec2..030a2bc89 100644 --- a/src/core/execution/NationExecution.ts +++ b/src/core/execution/NationExecution.ts @@ -14,6 +14,7 @@ import { UnitType, } from "../game/Game"; import { TileRef, euclDistFN } from "../game/GameMap"; +import { canBuildTransportShip } from "../game/TransportShipUtils"; import { PseudoRandom } from "../PseudoRandom"; import { GameID } from "../Schemas"; import { boundingBoxTiles, calculateBoundingBox, simpleHash } from "../Util"; @@ -501,6 +502,7 @@ export class NationExecution implements Execution { if (this.player === null) throw new Error("not initialized"); const x = this.mg.x(tile); const y = this.mg.y(tile); + const unreachablePlayers = new Set(); for (let i = 0; i < 500; i++) { const randX = this.random.nextInt(x - 150, x + 150); const randY = this.random.nextInt(y - 150, y + 150); @@ -515,6 +517,10 @@ export class NationExecution implements Execution { if (owner === this.player) { continue; } + // Skip players we already know are unreachable (Performance optimization) + if (owner.isPlayer() && unreachablePlayers.has(owner.id())) { + continue; + } // Don't send boats to players with which we share a border, that usually looks stupid if (owner.isPlayer() && borderingEnemies.includes(owner)) { continue; @@ -523,17 +529,28 @@ export class NationExecution implements Execution { if (owner.isPlayer() && owner.troops() > this.player.troops() * 2) { continue; } - // High-interest targeting: prioritize unowned tiles or tiles owned by bots + + let matchesCriteria = false; if (highInterestOnly) { - if (!owner.isPlayer() || owner.type() === PlayerType.Bot) { - return randTile; - } + // High-interest targeting: prioritize unowned tiles or tiles owned by bots + matchesCriteria = !owner.isPlayer() || owner.type() === PlayerType.Bot; } else { // Normal targeting: return unowned tiles or tiles owned by non-friendly players - if (!owner.isPlayer() || !owner.isFriendly(this.player)) { - return randTile; - } + matchesCriteria = !owner.isPlayer() || !owner.isFriendly(this.player); } + if (!matchesCriteria) { + continue; + } + + // Validate that we can actually build a transport ship to this target + if (canBuildTransportShip(this.mg, this.player, randTile) === false) { + if (owner.isPlayer()) { + unreachablePlayers.add(owner.id()); + } + continue; + } + + return randTile; } return null; }