Algorithm 创建游戏场的算法
我目前正在寻找一种方法来检查是否每个字段都可以访问,如果可以,是否有一种方法可以在不使用字段两次的情况下访问每个字段。 我现在的想法是从各个方向开始,把用过的土地当作新的墙。如果机器人手被卡住,他会重新启动并转向另一个方向。但我不确定这是否有效。 演出怎么样?这行得通吗 世界/墙壁和机器人的位置是随机的。 机器人驾驶员不得使用他以前使用过的场地 下面是一个示例图像。Algorithm 创建游戏场的算法,algorithm,logic,Algorithm,Logic,我目前正在寻找一种方法来检查是否每个字段都可以访问,如果可以,是否有一种方法可以在不使用字段两次的情况下访问每个字段。 我现在的想法是从各个方向开始,把用过的土地当作新的墙。如果机器人手被卡住,他会重新启动并转向另一个方向。但我不确定这是否有效。 演出怎么样?这行得通吗 世界/墙壁和机器人的位置是随机的。 机器人驾驶员不得使用他以前使用过的场地 下面是一个示例图像。 根据您的输入,您可以使用一个搜索引擎,以机器人的起始位置作为树的根来搜索整个世界。通常使用BFS,您会记住在这种特定情况下您已经看
根据您的输入,您可以使用一个搜索引擎,以机器人的起始位置作为树的根来搜索整个世界。通常使用BFS,您会记住在这种特定情况下您已经看到的“节点”或分幅。当算法终止时,您可以检查访问的节点列表是否等于要访问的节点列表
我认为,如果您知道每个磁贴的相邻节点(例如,通过引用),就可以这样做.这个问题可以建模为一个图中的连通性问题,我们可以在迷宫中运行一次深度优先搜索,并找到从起始位置可以到达的每个位置,如果任何位置不是墙/块,并且在运行DFS后未访问过,则您无法从任何位置之后的起始位置到达该位置迷宫中的路径 基本上,您需要将游戏中的每个位置表示为图形中的一个节点,其中每个节点都有其北、东、南和西墙的标志。当您希望通过边访问相邻位置时,您只能在相邻位置的墙未朝您尝试来自的方向时进行访问。因此,您所需要做的就是修改DFS算法,以便只有在没有墙的情况下才能访问/调用相邻节点上的DFS
void explore(Node position)
{
position.visited = true
while(position.hasUnvisitedDirection())
{
//random unvisited direction
int direction = position.getDirection();
if(direction == WEST && !west(node).visited && !position.westWall)
explore(west(node));
if(direction == EAST && !east(node).visited && !position.eastWall)
explore(east(node));
if(direction == SOUTH && !south(node).visited && !position.southWall)
explore(south(node));
if(direction == NORTH && !north(node).visited && !position.northWall)
explore(north(node));
}
}
这里我们对DFS做了一个修改,我们在每个访问的位置随机选择一个未访问的位置。east(Node)
、north(Node)
等调用将分别返回传递节点的位置east、north-注意网格中的边情况(如果将图形建模为二维数组,这非常直观)
接下来,我们要检查图是否只有一个强连接组件,如果DFS中只有一个跳转,则情况就是这样,即我们将在深度优先搜索林中有一棵树,并且每个位置都可以从您想要的起始位置到达。否则,运行DFS后未访问的节点将无法访问,如果算法返回false,则可以在运行DFS后检查这些位置。因此,应通过以下措施实现这一目标:
boolean isConnected(Graph g, Node startPosition)
{
int jumps = 0;
for (Node node : g.nodes())
{
if(!node.visited)
{
jumps++;
if(jumps > 1) return false;
else explore(position);
}
}
return true;
}
可用于解决上述迷宫。所有单元的可达性都很简单,每个单元只有一个布尔矩阵“可达”,从机器人的起始位置开始传播连通性信息,确保所有单元都已标记。这与世界大小成线性关系,因此没有问题 对于非冗余路径,基本上你需要一个启发式,因为正如在其他答案中已经提到的,哈密顿路径问题是NP。然后编写一个BFS或DFS遍历搜索空间,寻找获胜路径 我使用了下面的启发式方法,在“棋盘马”上可以很好地进行缩放,在“骑士”中,你必须覆盖棋盘上的所有位置。如果你从拓扑学的角度来看,这和你的问题是一样的 因此,启发式:
- 在每个单元格中,计算出您可以从中解脱出来的方法的数量。将此信息存储在矩阵中。所以中间的一个单元格有4个,墙旁边的一个单元格只有3个等等
- 在DFS中的每个决策点,选择下一个单元格作为退出次数最少的单元格(这是启发式的核心)
- 如果两个相邻的单元位于1个传出出口处,回溯,则此分支上的问题已消失
- 当您输入单元格时,相邻单元格的减量将退出
我使用这种启发式方法,即使在比经典的8x8更大的棋盘上,也能轻松地吐出许多解决方案 我已经实现了类似的东西来解决一个被称为“骑士之旅”的难题。我认为,这个问题应该基本上涉及相同的逻辑,只需稍作修改 我不会谈论遍历,我会尝试让它更容易理解-从任何给定的点,回答“下一步最好的动作是什么?”的问题,你想进一步思考并问:“什么是最具限制性的因素?”在这种情况下,最具限制性的因素,基于你的下一步可用动作,是指每个移动可以使用的移动数。你的每一个下一步行动都有自己的下一步行动。下一个可用移动次数最少的下一个可用移动是您的最大限制因素 例如,假设我有移动x,y和z。x和z都有2个下一步可用移动,y有3个下一步可用移动-你想移动到x或z(你决定哪个不重要,所以你可以像我在代码中做的那样随机化) 为什么这有意义?换一种方式考虑一下——下一步可用的移动(在我们的示例中是x、y和z)都是您在某个时候必须到达的点!对于x、y和z的下一步可用移动,也可以考虑将返回到x、y或z的方式。从那以后