首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Java迷宫解算器-我从来没有被困住过

Java迷宫解算器-我从来没有被困住过
EN

Stack Overflow用户
提问于 2013-04-04 17:18:20
回答 1查看 871关注 0票数 4

因此,我的任务是创建一个带有Queue、Set、Location对象和Cell对象的迷宫解算器,最终形成一个迷宫对象。

为了快速了解一下我的所有代码在完成后将做些什么:

代码语言:javascript
运行
复制
7
10
   _ _ _ _ _ _ _ _ _
|_ _ _  |  _ _   _  |
|  _ _| | |  _  |   |
| |   | |_| | | |_| |
|_ _|_ _   _| |_  | |
|  _    | |  _ _| |_|
| |_ _|  _|   |_    |
|_ _ _ _|_ _|_ _ _| |

如下所示:

代码语言:javascript
运行
复制
 @ _ _ _ _ _ _ _ _ _
|@ @ @ @|  _ _   _  |
|  _ _|@| |@ @ @|   |
| |   |@|_|@| |@|_| |
|_ _|_ @ @ @| |@ @| |
|  _    | |  _ _|@|_|
| |_ _|  _|   |_ @ @|
|_ _ _ _|_ _|_ _ _|@|
                   @

到目前为止,我所做的一切都很好,但是当我实际编写Maze对象中的findPath()方法时,我的代码生成了一个无效的路径。当我接收一个文件来读取迷宫时,我将该迷宫转换为一个多维字符数组,然后将该字符数组转换为一个多维单元数组,并使用布尔值映射每个单元的边界北、南、东和西。

现在,我要弄清楚如何在迷宫中导航,我在迷宫的findPath()方法中尝试过,但实际上失败了。

代码语言:javascript
运行
复制
 @  @  @  @  .  .  .  .  .  . 
 .  .  .  @  .  .  .  .  .  . 
 .  @  @  @  .  .  .  .  .  . 
 .  @  @  @  @  .  .  .  .  . 
 .  .  @  @  @  .  .  .  .  . 
 .  @  @  @  @  .  .  .  .  . 
 .  .  .  .  .  .  .  .  .  . 

首先,为了说明我应该实现的目标,让我先看一下我的需求文档:

代码语言:javascript
运行
复制
The algorithm operates according to the following pseudo-code:

* Visit the starting Location.
* Add this Location to the set.
* Enqueue the Location in the queue.

while (ArrayQueue<E> != empty( )) 
{
    Dequeue a Location(next) from the queue

        For each neighbor of Location(next) which has
         not yet been placed in the set, repeat:
                * Visit the neighbor of Location(next).
                * Add the neighbor of Location(next) to the Set.
                * Enqueue the neighbor of Location(next)in the Queue.
 }

我几乎可以肯定,我在某种程度上正确地使用了他的算法,但我不知道我做错了什么,才得到了我遇到的路径。我最头疼的是迷宫对象的findPath()方法,我把它包含在下面。我想我最大的问题是我做错了什么?我已经做了好几天了,就是想不通。任何帮助都是非常感谢的。我的代码如下:

我的迷宫的findpath方法

代码语言:javascript
运行
复制
public void findPath()
{
    Location startLocation = new Location(0, 0);
    theMaze[startLocation.getRow()][startLocation.getColumn()].setVisited(true);

    Location endLocation = new Location(6, 9);

    Location cursor;

    locationQueue.enqueue(startLocation);
    locationSet.enter(startLocation);

    while(!locationQueue.isEmpty())
    {
        cursor = locationQueue.dequeue();

        if(cursor == endLocation)
            break;

        for(int i = 0; i < 4; i++)
        {
            Location temp = cursor.getLoc(i);

            if(theMaze[cursor.getRow()][cursor.getColumn()].validDirection(i) && (!locationSet.isElement(temp)) && !(theMaze[temp.getRow()][temp.getColumn()].isVisited()))
            {
                cursor = cursor.getLoc(i);
                theMaze[cursor.getRow()][cursor.getColumn()].setVisited(true);

                if(theMaze[cursor.getColumn()][cursor.getColumn()].getPathAmount() < 2)
                {
                    cursor = startLocation;
                    continue;
                }

                locationSet.enter(cursor);
                locationQueue.enqueue(cursor);                          
            }               
        }           
    }

    for(int i = 0; i < locationSet.size(); i++)
    {
        System.out.println("Row " + locationSet.get(i).getRow() + " Column " + locationSet.get(i).getColumn());
        theMaze[locationSet.get(i).getRow()][locationSet.get(i).getColumn()].setPath();
    }

    for(int i = 0; i < theMaze.length; i++)
    {
        for(int j = 0; j < theMaze[i].length; j++)
        {
            System.out.print(theMaze[i][j].toString());
        }
        System.out.print("\n");
    }

}

编辑:我的问题是迷宫对象,而不是其他类,所以我基本上是在清理。

EN

回答 1

Stack Overflow用户

发布于 2013-04-04 17:30:17

你的基本算法有缺陷。您只需将单元格添加到路径中,但如果它们被证明是死胡同,则不要删除它们。

这类问题最适合于递归算法。

代码语言:javascript
运行
复制
function findExit(gameMap, listOfVisitedCells, currentCell, solution)
    listOfVisitedCells.add(currentCell);
    for each gameMap.NeighbourOf(currentCell)
        if neighbour not in listOfVisitedCells
             solution.add(neighbour)
             if (gameMap.isExit(neighbour)) {
               return true;
             }
             if (findExit(gameMap, listOfVisitedCells, currentCell, solution)) {
               return true;
             }
             solution.remove(neighbour);
        }
    }
    // No neighbours of the current cell got to find the exit.
    return false;
 }

当然,这将首先探索地图深度,因此如果有几条路径有效,则不能保证找到最短的路径(为此使用Djikstra算法)。

更新:查看您的代码:

在心理上调试这么多行代码是很困难的,因此花足够的时间与您选择的调试器在一起,观察程序的实际状态与预期状态,等等也是很困难的。不要期望太多,所以更适合用有限的代码量来解决具体的问题(“我希望这段代码能做到这一点,但它没有做到,为什么”)。

无论如何,这让我觉得很奇怪:

代码语言:javascript
运行
复制
        Location temp = cursor.getLoc(i);

        if(theMaze[cursor.getRow()][cursor.getColumn()].validDirection(i) && (!locationSet.isElement(temp)) && !(theMaze[temp.getRow()][temp.getColumn()].isVisited()))
        {
            cursor = cursor.getLoc(i);       <-- Why are you overwritting the current
                                             <-- location when you have still not checked
                                             <-- all the posible directions?
            theMaze[cursor.getRow()][cursor.getColumn()].setVisited(true);

            if(theMaze[cursor.getColumn()][cursor.getColumn()].getPathAmount() < 2)
            {
                cursor = startLocation;
                continue;
            }

            locationSet.enter(cursor);
            locationQueue.enqueue(cursor);                          
        }               

我敢打赌这是不正确的。当然,也许还有其他问题隐藏着,如果你尝试自己调试它,找出不能像预期那样工作的片段,这会更好(并给你更多的经验)(然后,如果需要,请在SO中寻求帮助)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15807137

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档