Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/143.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 映射分支平铺路径_C++_Algorithm_Pathing_Tile Engine - Fatal编程技术网

C++ 映射分支平铺路径

C++ 映射分支平铺路径,c++,algorithm,pathing,tile-engine,C++,Algorithm,Pathing,Tile Engine,我正在做一个游戏(已经问了几个问题),现在我有另一个问题要问你们 这个游戏中的关卡格式设置为Uint16的tilemap(我使用的是SDL),它是tilemapData结构数组的索引。tilemapData结构的一个位是isConductive位/布尔值 这一点的使用基本上是为了创建将各种对象连接到一个“powerNet”中的路径。下面我有一些关于当前方法的代码(这是可行的,但我会在后面讲述我为什么讨厌它) void findSetPoweredObjects(无符号长x、无符号长y、power

我正在做一个游戏(已经问了几个问题),现在我有另一个问题要问你们

这个游戏中的关卡格式设置为Uint16的tilemap(我使用的是SDL),它是tilemapData结构数组的索引。tilemapData结构的一个位是isConductive位/布尔值

这一点的使用基本上是为了创建将各种对象连接到一个“powerNet”中的路径。下面我有一些关于当前方法的代码(这是可行的,但我会在后面讲述我为什么讨厌它)

void findSetPoweredObjects(无符号长x、无符号长y、powerNetInfo*powerNet){
//在此互动程序上查找PoweredObj,并将其powerNet设置为给定的powerNet
对于(int i=0;inumChunks[CHUNKTYPE_POWEREDDEF];i++)
如果(级别->poweredObjects[i]->position[0]==x和级别->poweredObjects[i]->position[1]==y)
level->poweredObjects[i]->powerNet=powerNet,powerNet->objectsinet++;
}
void recursiveCheckTile(bool*iswalk、powerNetInfo*powerNet、无符号长x、无符号长y、tilemapData*levelMap){
//如果超出范围,请返回
如果(x<0 | | y<0 | | x>=level->mapDimensions[0]| | y>=level->mapDimensions[1])返回;
//如果瓦片已经走了,返回
如果(Iswalk[x+(y*级别->mapDimensions[0]))返回;
//如果瓷砖不导电,则返回
如果(!(level->tiles[levelMap->map[x+(y*level->mapDimensions[0])]->flags&TILETYPE\u)返回;
//要检查有效的磁贴,请查看磁贴上是否有poweredobj(如果有,请将其链接到网络),并检查相邻的磁贴。
iswalk[x+(y*级别->地图维度[0])]=true;
FindSetPoweredObject(x、y、powerNet);
递归CheckTile(iWalk、powerNet、x-1、y、levelMap);
recursiveCheckTile(iWalk、powerNet、x+1、y、levelMap);
递归CheckTile(iWalk、powerNet、x、y-1、levelMap);
recursiveCheckTile(iWalk、powerNet、x、y+1、levelMap);
}
bool buildPowerNets(void){
//构建受电对象使用的电力网
//TODO:重写buildPowerNets()&recursiveCheckTile(),以避免堆栈溢出,并使在游戏中回溯powernets更容易
布尔*伊斯沃克;
iswalk=new bool[(级别->地图维度[0]*级别->地图维度[1]);
无符号长x,y;
tilemapData*levelMap=level->layers[level->activeMap];
对于(y=0;ymapDimensions[1];y++){
对于(x=0;xmapDimensions[0];x++){
如果(Iswalk[x+(y*级别->mapDimensions[0]))继续;
iswalk[x+(y*级别->地图维度[0])]=true;
if(level->tiles[levelMap->map[x+(y*level->mapDimensions[0])]->flags&TILETYPE\u{
//它是导电的,找出它连接的是什么。
//但首先,创建一个新的powernet
powerNetInfo*powerNet=新的powerNetInfo;
powerNet->objectsinet=0;
powerNet->producerId=-1;
powerNet->supplyType=电源关闭;
powerNet->prevSupplyType=电源关闭;
powerNet->powerFor=0;
//找到与此相邻的磁贴,将它们添加到powernet,然后标记它们已漫游。然后重复此操作,直到完成联网。
recursiveCheckTile(iWalk、powerNet、x、y、levelMap);
}
}
}
删除iswalk;
对于(int i=0;inumChunks[CHUNKTYPE_POWEREDDEF];i++)
if(level->poweredObjects[i]->powerNet==NULL)返回false;
返回true;
}
请注意,返回false表示函数失败(在本例中,它没有正确链接所有对象)

我担心的是,由于堆栈溢出,在更复杂的贴图上行走导电瓷砖的功能将完全失败。对于如何利用这些功能来缓解这种风险,有什么想法?如果需要,我可以提供有关所用结构的更多信息

我曾经考虑过修改代码,使
recursiveCheckTile
仅在它到达一个连接点时进行递归调用,并且只是交互地沿着它打开的导电路径,否则,这似乎仍然只是一个部分解决方案,因为我无法提前知道路径可能有多扭曲或分支


如果有区别的话,速度在这里是完全不重要的,因为这个函数在使用之前只在地图被处理时运行一次,所以使用一点额外的时间不会有什么坏处。

您可以迭代地重写这个函数

可以这样想:您隐式地使用调用堆栈作为搜索算法的路径堆栈。每次调用
recursiveCheckTile
时,都会将一个节点推到该堆栈上。然而,调用堆栈相对较小,因此您很快就会将其耗尽

您需要显式地管理路径堆栈。不要为四个相邻的节点调用递归函数,而是将一个节点推到这个显式堆栈上。您的算法将如下所示(伪):

这将产生相同的遍历(深度优先),但堆栈将是显式的,因此您可以为其分配大量内存。

Flood fill 看起来你基本上是在做网格的一部分。您可以通过使用需要检查的队列或正方形堆栈来消除递归。有关伪代码,请参阅Wikipedia文章的

自己维护队列/堆栈的好处是,您将在访问方块时从列表中删除方块,而在递归解决方案中,即使在您访问方块之后,方块仍保留在堆栈上

以下是维基百科文章中的“简单”替代实现,适用于您的问题:

1. Set Q to the empty queue.
2. Add node to the end of Q.
3. While Q is not empty: 
4.     Set n equal to the first element of Q
5.     Remove first element from Q
6.     If n has already been visited:
7.         Go back to step 3.
8.     Mark n as visited.
9.     Add the node to the west to the end of Q.
10.    Add the node to the east to the end of Q.
11.    Add the node to the north to the end of Q.
12.    Add the node to the south to the end of Q.
13. Return.
请注意,您可以为此使用堆栈或队列,两者都可以。以下是一些酷而迷人的动画,从视觉上展示了不同之处:

基于队列的洪水填充

基于叠加的洪水填充

连接元件标签 如果你在同一个电网上有多个电网,你也会发现这个页面很有趣。它基本上对你有帮助
add starting node to stack

while( nodes on stack )
{
    pop node
    if( node is conductive )
    {
        add node to powerSet
        push 4 adjoining nodes onto stack
    }
}
1. Set Q to the empty queue.
2. Add node to the end of Q.
3. While Q is not empty: 
4.     Set n equal to the first element of Q
5.     Remove first element from Q
6.     If n has already been visited:
7.         Go back to step 3.
8.     Mark n as visited.
9.     Add the node to the west to the end of Q.
10.    Add the node to the east to the end of Q.
11.    Add the node to the north to the end of Q.
12.    Add the node to the south to the end of Q.
13. Return.