平铺地图JavaScript中的算法填充封闭区域
Posted
技术标签:
【中文标题】平铺地图JavaScript中的算法填充封闭区域【英文标题】:Algorithm Fill Closed Area in Tile map JavaScript 【发布时间】:2020-03-21 04:36:56 【问题描述】:对不起我的英语。
我有一个问题,下一步是什么:
例如,我有一张地图:
var map =
[[0,1,1,0,0,0,0,0,0,0],
[0,1,0,1,0,1,1,0,0,0],
[0,1,0,0,1,0,0,1,0,0],
[0,1,0,0,0,0,0,0,1,0],
[0,0,1,0,0,0,0,1,0,0],
[0,0,0,1,0,0,0,1,1,0],
[0,0,1,0,0,0,1,0,0,0],
[0,1,0,0,0,0,0,1,0,0],
[1,0,0,1,1,1,0,1,0,0],
[0,1,1,0,0,1,1,1,0,0]];
其中包含一系列数字 0 和 1(例如)。我需要填写此地图上所有封闭的方框,例如使用数字 2。
例子:
var map =
[[0,1,1,0,0,0,0,0,0,0],
[0,1,2,1,0,1,1,0,0,0],
[0,1,2,2,1,2,2,1,0,0],
[0,1,2,2,2,2,2,2,1,0],
[0,0,1,2,2,2,2,1,0,0],
[0,0,0,1,2,2,2,1,1,0],
[0,0,1,2,2,2,1,0,0,0],
[0,1,2,2,2,2,2,1,0,0],
[1,2,2,1,1,1,2,1,0,0],
[0,1,1,0,0,1,1,1,0,0]];
考虑到:
-
正如本例中只有一个闭合图形,也可以有多个闭合图形
不会考虑地图的侧面
如果有任何用处,数字 1(将是实心)将
随着时间的推移生成,所以地图会不断变化
(就像数组中的笔划)
我找到了一个名为“Flood Fill”的方法,但是它取决于一个起点,在这种情况下它没有起点。这个想法是代码负责找到封闭区域并自动填充它们。
【问题讨论】:
【参考方案1】:如果您没有起始坐标,识别要填充的每个 0 的一种方法是识别边缘上的每个 0。这些零中的每一个都应该不被填充,并且最终与这些0相邻的每个0也不应该被填充。因此,如果您将边缘 0 作为“起点”并遍历它们的所有递归邻居,您将识别出每个坐标为 0 但不应填充。
然后,这很简单:只需遍历输入,对于每个 0,检查当前坐标是否在不应填充的那组坐标中。如果坐标在该集合中不是,则替换为 2。
var map =
[[0,1,1,0,0,0,0,0,0,0],
[0,1,2,1,0,1,1,0,0,0],
[0,1,2,2,1,2,2,1,0,0],
[0,1,2,2,2,2,2,2,1,0],
[0,0,1,2,2,2,2,1,0,0],
[0,0,0,1,2,2,2,1,1,0],
[0,0,1,2,2,2,1,0,0,0],
[0,1,2,2,2,2,2,1,0,0],
[1,2,2,1,1,1,2,1,0,0],
[0,1,1,0,0,1,1,1,0,0]];
const height = map.length;
const width = map[0].length;
const edgeZerosCoords = new Set();
map.forEach((arr, row) =>
arr.forEach((num, col) =>
if (num === 0 && (row === 0 || col === 0 || row === width - 1 || col === height - 1))
edgeZerosCoords.add(`$row_$col`);
)
);
const doNotFillCoords = new Set();
const visited = new Set();
const checkCoord = (row, col) =>
// Verify valid coord:
if (row < 0 || col < 0 || row === width || col === height) return;
const str = `$row_$col`;
if (doNotFillCoords.has(str) || visited.has(str)) return;
visited.add(str);
const num = map[row][col];
if (num !== 0) return;
doNotFillCoords.add(str);
checkCoord(row + 1, col);
checkCoord(row - 1, col);
checkCoord(row, col + 1);
checkCoord(row, col - 1);
;
for (const str of edgeZerosCoords)
const [row, col] = str.split('_').map(Number);
checkCoord(row, col)
map.forEach((arr, row) =>
arr.forEach((num, col) =>
const str = `$row_$col`;
if (num === 0 && !doNotFillCoords.has(str))
map[row][col] = 2;
)
);
console.log(JSON.stringify(map));
结果:
[
[0, 1, 1, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 2, 1, 0, 1, 1, 0, 0, 0],
[0, 1, 2, 2, 1, 2, 2, 1, 0, 0],
[0, 1, 2, 2, 2, 2, 2, 2, 1, 0],
[0, 0, 1, 2, 2, 2, 2, 1, 0, 0],
[0, 0, 0, 1, 2, 2, 2, 1, 1, 0],
[0, 0, 1, 2, 2, 2, 1, 0, 0, 0],
[0, 1, 2, 2, 2, 2, 2, 1, 0, 0],
[1, 2, 2, 1, 1, 1, 2, 1, 0, 0],
[0, 1, 1, 0, 0, 1, 1, 1, 0, 0]
]
【讨论】:
非常感谢,我就是这个意思以上是关于平铺地图JavaScript中的算法填充封闭区域的主要内容,如果未能解决你的问题,请参考以下文章