From 6e39f216629a94c33ebd332bbd901be9cf83adfd Mon Sep 17 00:00:00 2001 From: variablevince <24507472+VariableVince@users.noreply.github.com> Date: Sun, 26 Oct 2025 02:43:14 +0100 Subject: [PATCH] Caching added, testversion --- src/core/game/TransportShipUtils.ts | 124 ++++++++++++++++++++++------ 1 file changed, 99 insertions(+), 25 deletions(-) diff --git a/src/core/game/TransportShipUtils.ts b/src/core/game/TransportShipUtils.ts index 456853372..f659b54af 100644 --- a/src/core/game/TransportShipUtils.ts +++ b/src/core/game/TransportShipUtils.ts @@ -2,31 +2,90 @@ import { PathFindResultType } from "../pathfinding/AStar"; import { MiniAStar } from "../pathfinding/MiniAStar"; import { Game, Player, UnitType } from "./Game"; import { andFN, GameMap, manhattanDistFN, TileRef } from "./GameMap"; +interface CacheEntry { + tick: number; + value: T; +} + +const transportTileCache = new Map>(); +const buildTransportShipCache = new Map>(); + +function getTransportTileCacheKey(tile: TileRef, tick: number): string { + return `transport_${tile}_${tick}`; +} + +function getBuildCacheKey( + playerId: string, + tile: TileRef, + tick: number, +): string { + return `build_${playerId}_${tile}_${tick}`; +} + +let lastCleanupTick = 0; + +function cleanupCache( + cache: Map>, + currentTick: number, + cacheName: string, //TODO: remove after testing +): void { + if (currentTick < lastCleanupTick + 20) { + return; + } + lastCleanupTick = currentTick; + + for (const [key, entry] of cache.entries()) { + if (entry.tick < currentTick) { + console.log( + `Cleaning up ${cacheName} cache for key ${key} at tick ${entry.tick}`, + ); + cache.delete(key); + } + } +} export function canBuildTransportShip( game: Game, player: Player, tile: TileRef, ): TileRef | false { + const currentTick = game.ticks(); + const key = getBuildCacheKey(player.id(), tile, currentTick); + + const cached = buildTransportShipCache.get(key); + if (cached?.tick === currentTick) { + console.log( + "Using cached canBuildTransportShip for player " + + player.id() + + " tile " + + tile + + " at tick " + + currentTick, + ); //TODO: remove after testing + return cached.value; + } + if ( player.unitCount(UnitType.TransportShip) >= game.config().boatMaxNumber() ) { + buildTransportShipCache.set(key, { tick: currentTick, value: false }); return false; } const other = game.owner(tile); - if (other === player) { - return false; - } - if (other.isPlayer() && player.isFriendly(other)) { + if (other === player || (other.isPlayer() && player.isFriendly(other))) { + buildTransportShipCache.set(key, { tick: currentTick, value: false }); return false; } const dst = targetTransportTile(game, tile); if (dst === null) { + buildTransportShipCache.set(key, { tick: currentTick, value: false }); return false; } + let result: TileRef | false = false; + if (game.isOceanShore(dst)) { let myPlayerBordersOcean = false; for (const bt of player.borderTiles()) { @@ -35,32 +94,32 @@ export function canBuildTransportShip( break; } } - if (myPlayerBordersOcean) { - return transportShipSpawn(game, player, dst); - } else { - return false; + result = transportShipSpawn(game, player, dst); + } + } else { + const tiles = game.bfs( + dst, + andFN( + manhattanDistFN(dst, 300), + (_, t: TileRef) => game.isLake(t) || game.isShore(t), + ), + ); + const sorted = Array.from(tiles).sort( + (a, b) => game.manhattanDist(dst, a) - game.manhattanDist(dst, b), + ); + for (const t of sorted) { + if (game.owner(t) === player) { + result = transportShipSpawn(game, player, t); + break; + } } } - const tiles = game.bfs( - dst, - andFN( - manhattanDistFN(dst, 300), - (_, t: TileRef) => game.isLake(t) || game.isShore(t), - ), - ); + buildTransportShipCache.set(key, { tick: currentTick, value: result }); + cleanupCache(buildTransportShipCache, currentTick, "buildTransportShip"); //TODO: remove last param after testing - const sorted = Array.from(tiles).sort( - (a, b) => game.manhattanDist(dst, a) - game.manhattanDist(dst, b), - ); - - for (const t of sorted) { - if (game.owner(t) === player) { - return transportShipSpawn(game, player, t); - } - } - return false; + return result; } function transportShipSpawn( @@ -79,6 +138,17 @@ function transportShipSpawn( } export function targetTransportTile(gm: Game, tile: TileRef): TileRef | null { + const currentTick = gm.ticks(); + const key = getTransportTileCacheKey(tile, currentTick); + + const cached = transportTileCache.get(key); + if (cached?.tick === currentTick) { + console.log( + "Using cached transport tile for " + tile + " at tick " + currentTick, + ); //TODO: remove after testing + return cached.value; + } + const dst = gm.playerBySmallID(gm.ownerID(tile)); let dstTile: TileRef | null = null; if (dst.isPlayer()) { @@ -86,6 +156,10 @@ export function targetTransportTile(gm: Game, tile: TileRef): TileRef | null { } else { dstTile = closestShoreTN(gm, tile, 50); } + + transportTileCache.set(key, { tick: currentTick, value: dstTile }); + cleanupCache(transportTileCache, currentTick, "transportTile"); //TODO: remove last param after testing + return dstTile; }