allow boating on lakes

This commit is contained in:
Evan
2025-03-03 19:19:16 -08:00
parent 9fd1203d50
commit c1383d76f1
5 changed files with 68 additions and 55 deletions
+9 -9
View File
@@ -64,12 +64,12 @@ export function sourceDstOceanShore(
tile: TileRef,
): [TileRef | null, TileRef | null] {
const dst = gm.owner(tile);
let srcTile = closestOceanShoreFromPlayer(gm, src, tile);
let srcTile = closestShoreFromPlayer(gm, src, tile);
let dstTile: TileRef | null = null;
if (dst.isPlayer()) {
dstTile = closestOceanShoreFromPlayer(gm, dst as Player, tile);
dstTile = closestShoreFromPlayer(gm, dst as Player, tile);
} else {
dstTile = closestOceanShoreTN(gm, tile, 300);
dstTile = closestShoreTN(gm, tile, 50);
}
return [srcTile, dstTile];
}
@@ -78,20 +78,20 @@ export function targetTransportTile(gm: Game, tile: TileRef): TileRef | null {
const dst = gm.playerBySmallID(gm.ownerID(tile));
let dstTile: TileRef | null = null;
if (dst.isPlayer()) {
dstTile = closestOceanShoreFromPlayer(gm, dst as Player, tile);
dstTile = closestShoreFromPlayer(gm, dst as Player, tile);
} else {
dstTile = closestOceanShoreTN(gm, tile, 300);
dstTile = closestShoreTN(gm, tile, 50);
}
return dstTile;
}
export function closestOceanShoreFromPlayer(
export function closestShoreFromPlayer(
gm: GameMap,
player: Player,
target: TileRef,
): TileRef | null {
const shoreTiles = Array.from(player.borderTiles()).filter((t) =>
gm.isOceanShore(t),
gm.isShore(t),
);
if (shoreTiles.length == 0) {
return null;
@@ -112,7 +112,7 @@ export function closestOceanShoreFromPlayer(
});
}
function closestOceanShoreTN(
function closestShoreTN(
gm: GameMap,
tile: TileRef,
searchDist: number,
@@ -123,7 +123,7 @@ function closestOceanShoreTN(
andFN((_, t) => !gm.hasOwner(t), manhattanDistFN(tile, searchDist)),
),
)
.filter((t) => gm.isOceanShore(t))
.filter((t) => gm.isShore(t))
.sort((a, b) => gm.manhattanDist(tile, a) - gm.manhattanDist(tile, b));
if (tn.length == 0) {
return null;
+1 -1
View File
@@ -128,7 +128,7 @@ export class PlayerExecution implements Execution {
const enemies = new Set<number>();
for (const tile of cluster) {
const isOceanShore = this.mg.isOceanShore(tile);
if (this.mg.isShore(tile) && !isOceanShore) {
if (this.mg.isOceanShore(tile) && !isOceanShore) {
continue;
}
if (
+1 -1
View File
@@ -281,9 +281,9 @@ export class GameMapImpl implements GameMap {
q.push(tile);
while (q.length > 0) {
const curr = q.pop();
seen.add(curr);
for (const n of this.neighbors(curr)) {
if (!seen.has(n) && filter(this, n)) {
seen.add(n);
q.push(n);
}
}
+56 -43
View File
@@ -24,7 +24,7 @@ import { GameUpdateType } from "./GameUpdates";
import { ClientID } from "../Schemas";
import {
assertNever,
closestOceanShoreFromPlayer,
closestShoreFromPlayer,
distSortUnit,
maxInt,
minInt,
@@ -731,10 +731,10 @@ export class PlayerImpl implements Player {
}
transportShipSpawn(targetTile: TileRef): TileRef | false {
if (!this.mg.isOceanShore(targetTile)) {
if (!this.mg.isShore(targetTile)) {
return false;
}
const spawn = closestOceanShoreFromPlayer(this.mg, this, targetTile);
const spawn = closestShoreFromPlayer(this.mg, this, targetTile);
if (spawn == null) {
return false;
}
@@ -782,7 +782,6 @@ export class PlayerImpl implements Player {
}
public canBoat(tile: TileRef): boolean {
const other = this.mg.owner(tile);
if (
this.units(UnitType.TransportShip).length >=
this.mg.config().boatMaxNumber()
@@ -790,54 +789,68 @@ export class PlayerImpl implements Player {
return false;
}
let myPlayerBordersOcean = false;
for (const bt of this.borderTiles()) {
if (this.mg.isOceanShore(bt)) {
myPlayerBordersOcean = true;
break;
}
}
let otherPlayerBordersOcean = false;
if (!this.mg.hasOwner(tile)) {
otherPlayerBordersOcean = true;
} else {
for (const bt of (other as Player).borderTiles()) {
if (this.mg.isOceanShore(bt)) {
otherPlayerBordersOcean = true;
break;
}
}
const dst = targetTransportTile(this.mg, tile);
if (dst == null) {
return false;
}
const other = this.mg.owner(tile);
if (other == this) {
return false;
}
if (other.isPlayer() && this.allianceWith(other)) {
return false;
}
let nearOcean = false;
for (const t of this.mg.bfs(
tile,
andFN(
(gm, t) => gm.ownerID(t) == gm.ownerID(tile) && gm.isLand(t),
manhattanDistFN(tile, 25),
),
)) {
if (this.mg.isOceanShore(t)) {
nearOcean = true;
break;
}
}
if (!nearOcean) {
return false;
}
if (myPlayerBordersOcean && otherPlayerBordersOcean) {
const dst = targetTransportTile(this.mg, tile);
if (dst != null) {
if (this.canBuild(UnitType.TransportShip, dst)) {
return true;
if (this.mg.isOceanShore(dst)) {
let myPlayerBordersOcean = false;
for (const bt of this.borderTiles()) {
if (this.mg.isOceanShore(bt)) {
myPlayerBordersOcean = true;
break;
}
}
let otherPlayerBordersOcean = false;
if (!this.mg.hasOwner(tile)) {
otherPlayerBordersOcean = true;
} else {
for (const bt of (other as Player).borderTiles()) {
if (this.mg.isOceanShore(bt)) {
otherPlayerBordersOcean = true;
break;
}
}
}
if (myPlayerBordersOcean && otherPlayerBordersOcean) {
return this.canBuild(UnitType.TransportShip, dst) != false;
} else {
return false;
}
}
// Now we are boating in a lake, so do a bfs from target until we find
// a border tile owned by the player
const tiles = this.mg.bfs(
dst,
andFN(
manhattanDistFN(dst, 300),
(_, t: TileRef) => this.mg.isLake(t) || this.mg.isShore(t),
),
);
const sorted = Array.from(tiles).sort(
(a, b) => this.mg.manhattanDist(dst, a) - this.mg.manhattanDist(dst, b),
);
for (const t of sorted) {
if (this.mg.owner(t) == this) {
return this.canBuild(UnitType.TransportShip, dst) != false;
}
}
return false;
}
createAttack(
+1 -1
View File
@@ -33,7 +33,7 @@ export class PathFinder {
if (canMoveOnLand) {
return true;
}
return game.miniMap().isOcean(tr);
return game.miniMap().isWater(tr);
},
iterations,
maxTries,