gpt4 book ai didi

java - 深度优先搜索 - 2D 游戏 map

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:20:55 25 4
gpt4 key购买 nike

我创建了一个 2D 迷宫,我想找到红色-> 蓝色节点之间的最快路径。我不确定我将如何实现深度优先搜索。我知道可以使用邻接矩阵或列表来表示节点之间的连接。虽然,我不确定如何构建它。

为简洁起见:我需要返回一个列表,其中包含搜索到的图 block 坐标(在寻找目标节点时),因此我可以描述迷宫中的搜索。或者我将如何为此构建邻接矩阵?以及相应的顶点列表?

深度优先搜索的一般结构

  1. 访问节点(单元格)(将已访问标志更改为真)
  2. 推送到堆栈
  3. 如果没有(弹出堆栈)则获取未访问的顶点(查看堆栈)- 更新迷宫模型 View

重复 1 - 3 直到栈为空

这是迷宫类的当前代码。

public class Maze {

//Tile ids
public static short OBSTICLE = 0;
public static short START_LOC_VALUE = -2;
public static short GOAL_LOC_VALUE = -3;

private int rows, cols;
private int numTiles;
private int[][] map;
private int[][] adjMatrix;
private Queue theQueue;

public Maze(int rows, int cols){
this.rows = rows;
this.cols = cols;

theQueue = new Queue();

numTiles = rows*cols;

map = new int[rows][cols];
adjMatrix = new int[rows][cols];

for (int i=0; i<rows; i++) {
for (int j=0; j<cols; j++) {
map[i][j] = 1;
}
}
}

/*
* Generate Maze
* @param numObstacles - number of obstacles
*/
public void generateMaze(int numObstacles){
for (int i = 0; i < numObstacles; i++)
setTile((int)(Math.random()*rows),(int)(Math.random()*cols), Maze.OBSTICLE);

//setTile((int)(Math.random()*rows),(int)(Math.random()*cols),Maze.START_LOC_VALUE);
//setTile((int)(Math.random()*rows),(int)(Math.random()*cols),Maze.GOAL_LOC_VALUE);
createAdjMatrix();
}

public void createAdjMatrix(){
for (int i=0; i<rows; i++) {
for (int j=0; j<cols; j++) {
if (map[i][j] == 1) {
addEdge(i,j);
}
}
}
}

/*
* Set Tile
* @param x - x cord
* @param y - y cord
* @param entity - OBSTICLE,START_LOC_VALUE or GOAL_LOC_VALUE ID
*/
public void setTile(int x, int y, short entity){
this.map[x][y] = entity;
}

public void addEdge(int start, int end) {//Start and end arguments index multidimensional array
adjMatrix[start][end] = 1;
adjMatrix[end][start] = 1;
}

public void bfs(int startDest, int goalDest) // breadth-first search
{
// begin at vertex 0
vertexList[startDest].wasVisited = true; // mark it
displayVertex(startDest); // display it
theQueue.enQueue(startDest); // insert at tail
int v2;

while (!theQueue.isEmpty()) // until queue empty,
{
int v1 = theQueue.deQueue(); // remove vertex at head

// until it has no unvisited neighbors
while ((v2 = getAdjUnvisitedVertex(v1)) != -1)
{ // get one,

vertexList[v2].wasVisited = true; // mark it
displayVertex(v2); // display it
theQueue.enQueue(v2); // insert it

} // end while(unvisited neighbors)
} // end while(queue not empty)

// queue is empty, so we’re done
for (int j = 0; j < nVerts; j++) // reset flags
vertexList[j].wasVisited = false;
}// end bfs()

/*
* Drawn Maze
* @param g - Graphics object
*/
public void draw(Graphics g){
for (int y = 0; y < cols; y++)
for (int x = 0; x < rows; x++) {
int val = map[x][y];

if (val==Maze.OBSTICLE) {
g.setColor(Color.BLACK);
g.fillRect(x*20, y*20, 20, 20);
}else if(val == Maze.START_LOC_VALUE){
g.setColor(Color.RED);
g.fillRect(x*20, y*20, 20, 20);
}else if(val==Maze.GOAL_LOC_VALUE){
g.setColor(Color.BLUE);
g.fillRect(x*20, y*20, 20, 20);
}else{
g.setColor(Color.BLACK);
g.drawRect(x*20, y*20, 20, 20);
}
}
}
}

当前 DFS 代码..

public void dfs(int vertexStart) // depth-first search
{
// begin at vertexStart
vertexList[vertexStart].wasVisited = true; // mark it
displayVertex(vertexStart); // display it
theStack.push(vertexStart); // push it

while (!theStack.isEmpty()) // until stack empty,
{
// get an unvisited vertex adjacent to stack top
int v = getAdjUnvisitedVertex(theStack.peek());

if (v == -1) // if no such vertex,
theStack.pop(); // pop a new one
else // if it exists,
{
vertexList[v].wasVisited = true; // mark it
displayVertex(v); // display it
theStack.push(v); // push it
}
} // end while
}

下图描绘了迷宫结构,它是伪随机生成的;最终的迷宫实现将得到改进。

Maze

谢谢,如果你能引导我朝着正确的方向前进,我会很充实......

最佳答案

对于 2D 迷宫,您可以简单地使用 Breadth First Search如果你有 n*n 迷宫,它会在 O(n2) 中找到它,而不是深度优先搜索。

但是还有另一种选择,它是一种标记和 BFS,并且可以在您的迷宫中运行(无需绘制图表)。

编号算法

理解广度优先搜索的一种有趣方法是按照这种方式进行(对于迷宫):

  1. 将所有单元格设置为0,将 block 设置为-1

  2. 从您的源位置开始将其设置为 1,将其全部标记为 02 的邻居,并将所有 2 保存在列表中。在那之后标记为02 到 3 的邻居,清除 2 的列表并保存 3 的列表然后继续到达目的地。在每个级别只是不改变源值。

  3. 现在假设你在目的地并且你想找到路径,你的目的地得分为m,找到得分为m-1的邻居,....并输出路径。

事实上 BFS 的正常和简单的方法是使用 Q,但我提供这个是因为它很简单并且因为它模拟了 Q 方式。

使用邻接矩阵

为了创建邻接矩阵,您应该命名节点和边,这样您就可以为边和节点创建如下类(我用伪 C# 编写的):

public class Edge
{

public Edge(Node start, Node end, decimal weight)
{
StartNode = ...,...,...
}
public Node StartNode;
public Node EndNode;
public decimal weight;
public bool IsDirected;
}

public class Node
{
public Node(int index)
{
this.Index = index;
}
public int Index;
public List<Edge> Edges = new List<Edge>();
public bool Visited = false;
}

现在你的图表是你的节点对象的列表:

public class Graph
{
public List<Node> Nodes = new List<Node>();
}

对于迷宫建模,您应该选择单元格作为节点,并在相邻单元格之间绘制边。如何将节点添加到图形中,我将留给您。

关于java - 深度优先搜索 - 2D 游戏 map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9547295/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com