mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-23 06:49:37 +00:00
Caching added, testversion
This commit is contained in:
@@ -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<T> {
|
||||
tick: number;
|
||||
value: T;
|
||||
}
|
||||
|
||||
const transportTileCache = new Map<string, CacheEntry<TileRef | null>>();
|
||||
const buildTransportShipCache = new Map<string, CacheEntry<TileRef | false>>();
|
||||
|
||||
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<T>(
|
||||
cache: Map<string, CacheEntry<T>>,
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user