Optimize Water Tile Distance Calculation with BFS (Manhattan Distance) (#396)

## Description:
Replaced with BFS from shoreline tiles to propagate Manhattan distances
efficiently in O(W) time.
I’ve confirmed that the results match the previous implementation, but
please double-check on your end as well just to be safe.
I’d also like to get input from aPuddle.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors

## Please put your Discord username so you can be contacted if a bug or
regression is found:

<DISCORD USERNAME>
aotumuri
This commit is contained in:
Aotumuri
2025-04-03 02:22:37 +09:00
committed by GitHub
parent f58d9c1f8d
commit 4c776629f3
+43 -13
View File
@@ -120,19 +120,49 @@ function processShore(map: Terrain[][]): Coord[] {
}
function processDistToLand(shorelineWaters: Coord[], map: Terrain[][]) {
console.log("Setting Water tiles magnitude = distance from land");
for (let x = 0; x < map.length; x++) {
for (let y = 0; y < map[0].length; y++) {
const tile = map[x][y];
if (tile.type == TerrainType.Water) {
if (shorelineWaters.some((coord) => coord.x == x && coord.y == y)) {
tile.magnitude = 0;
} else {
const dist = shorelineWaters.map(
(coord) => Math.abs(x - coord.x) + Math.abs(y - coord.y),
);
tile.magnitude = Math.min(...dist);
}
console.log(
"Setting Water tiles magnitude = Manhattan distance from nearest land",
);
const width = map.length;
const height = map[0].length;
const visited = Array.from({ length: width }, () =>
Array(height).fill(false),
);
const queue: { x: number; y: number; dist: number }[] = [];
for (const { x, y } of shorelineWaters) {
queue.push({ x, y, dist: 0 });
visited[x][y] = true;
map[x][y].magnitude = 0;
}
const directions = [
{ dx: 0, dy: 1 },
{ dx: 1, dy: 0 },
{ dx: 0, dy: -1 },
{ dx: -1, dy: 0 },
];
while (queue.length > 0) {
const { x, y, dist } = queue.shift()!;
for (const { dx, dy } of directions) {
const nx = x + dx;
const ny = y + dy;
if (
nx >= 0 &&
ny >= 0 &&
nx < width &&
ny < height &&
!visited[nx][ny] &&
map[nx][ny].type === TerrainType.Water
) {
visited[nx][ny] = true;
map[nx][ny].magnitude = dist + 1;
queue.push({ x: nx, y: ny, dist: dist + 1 });
}
}
}