我正在通过Unity创建一个简单的六角形数学游戏。确实与Unity无关。
我从Image借来了https://catlikecoding.com/unity/tutorials/,以说明问题,它很大,因此将其放在链接中。
背景
与提供的链接中的教程相同,我使用一个数组来保存数据,以简化它,就像:
[ 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0 ]
我的目标是
检查一个或多个网格是否被另一种类型的网格包围。
定义
环绕意味着对于一个网格或一组连接的网格,所有邻居都处于不同的标记中。
例如,
[ 0, 1, 1, 0,
1, 0, 1, 0,
0, 1, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0 ]
//Should become
[ 0, 1, 1, 0,
1, 1, 1, 0,
0, 1, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0 ]
在这种情况下,我什至不需要算法,这很容易,因为我可以参照其邻居创建网格,例如
class grid{
grid[] neighbor;
int flag; //0 or 1
}
因此,当我需要检查网格是否被包围时,我只需要循环其neighbor
。
问题
但是,在以下情况下,这种方法很繁琐
[ 0, 1, 1, 1,
1, 0, 0, 1,
0, 1, 1, 1,
0, 0, 0, 0,
0, 0, 0, 0 ]
所以,我现在还需要检查其邻居的邻居,例如
foreach (grid i in neighbor){
bool is_surrounded = false;
if (grid.flag == 1) {
//Good
} else {
//Check its neighbor, if every neighbor except i is 1, then return True.
}
}
它对于2正常工作,但是如果有3个空白网格怎么办。递归不可行,例如当网格没有被包围时
[ 0, 1, 1, 1,
1, 0, 0, 1,
0, 1, 0, 1,
0, 0, 0, 0,
0, 0, 0, 0 ]
然后我将循环遍历整个地图,以进行大约8 ^ n次检查。
问题
我认为有一种我没有意识到的聪明方法,我欢迎任何种类/语言的答案,甚至只是一个想法。可以肯定的是,我会慷慨解囊并提供解释。
谢谢。
答案 0 :(得分:1)
首先,您必须进行严格的定义-什么区域称为“周围”。也许可行的方法是-单元格无法自由到达外部地图边缘。
要以这种方式进行检查-使用任何简单的遍历算法-例如DFS(路径查找算法在这里看起来过分杀伤-他们需要终点)
关于递归-您需要标记可见的单元格以避免重新检查。有floodfill个算法没有递归且具有很好的复杂性。
答案 1 :(得分:0)
您将对此倒退。您的编码逻辑看起来不错,但逻辑却相反。
对于每个存在的1,检查其周围是否可能存在其他1。如果您通过第一个1(从第一个1(返回)到第一个1)的任何路径返回,则您发现了一个闭环。找到返回路径来自的方向以重新调谐到第一个1,然后该方向就是循环内部的位置。然后,如果您对任何更深层次的循环都不感兴趣,请将该循环内的所有内容(包括1和0)标记为不再搜索。完成搜索,然后在搜索完成之后,并且只有在搜索完成之后,才将循环中的所有内部标记为1(如果这是您想要的)。这样,如果循环之外还有循环,那么您将不会一遍又一遍地重新启动。
对于子循环:将全1视为循环的可能起点。如果返回到先前的1,则找到来自哪个方向(在返回路径中),并考虑到循环的内部。
完成所有这些操作之后,您已经找到了循环,然后进行更改。不必担心循环的内部位置是否为零,因为0是有效大小,只需根据需要更改循环的所有可能内部即可。
谢谢。
B精益