[迷宫中的算法实践]迷宫生成算法——递归分割算法

发布时间:2017-3-23 10:20:28 编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"[迷宫中的算法实践]迷宫生成算法——递归分割算法 ",主要涉及到[迷宫中的算法实践]迷宫生成算法——递归分割算法 方面的内容,对于[迷宫中的算法实践]迷宫生成算法——递归分割算法 感兴趣的同学可以参考一下。

[迷宫中的算法实践]迷宫生成算法——递归分割算法

Recursive division method

       Mazes can be created with recursive division, an algorithm which works as follows: Begin with the maze's space with no walls. Call this a chamber. Divide the chamber with a randomly positioned wall (or multiple walls) where each wall contains a randomly positioned passage opening within it. Then recursively repeat the process on the subchambers until all chambers are minimum sized. This method results in mazes with long straight walls crossing their space, making it easier to see which areas to avoid.

       For example, in a rectangular maze, build at random points two walls that are perpendicular to each other. These two walls divide the large chamber into four smaller chambers separated by four walls. Choose three of the four walls at random, and open a one cell-wide hole at a random point in each of the three. Continue in this manner recursively, until every chamber has a width of one cell in either of the two directions.

Recursive Maze generation

 

递归分割算法

        可以用递归分割法创建迷宫,算法的工作原理如下:

        1.开始创建迷宫,使整个空间没有壁,我们称之为“室”。

        2.在随机位置生成壁将室分割为两个子室,并在壁上随机开孔,使子室联通。

        3.重复步骤2,直到所有子室全部不可分割(即子室某一个维度等于1)。


        例如,在矩形迷宫中,在任意点建立彼此垂直的两个壁。 这两个壁将大腔室分成由四个壁分开的四个较小腔室。 随机选择四个墙壁中的三个,并在三个墙壁的随机点处打开一个单元格的孔。 继续以这种方式递归,直到每个室在两个方向中的任一个方向上具有一个单元的宽度。

下面我们来做C#的代码实现:

/// <summary>
/// 递归回溯法迷宫生成法
/// </summary>
/// <param name="startX"></param>
/// <param name="startY"></param>
/// <param name="widthLimit"></param>
/// <param name="heightLimit"></param>
private void RecursiveBacktrack(int startX, int startY, int widthLimit, int heightLimit)
{
    PathStack = new Stack<Point>();
    //周围未连通格坐标
    int[] blockPos = new int[4];
    //周围未标记格的数量
    int blockNum = 0;

    //将起点作为当前格
    int currentX = startX;
    int currentY = startY;

    //标记起点
    MazeMap[currentX, currentY] = UnBlock;
    CreateScript.Add(new ScriptPoint(new Point(currentX, currentY), false));
    do
    {
        //检测周围有没有未连通的格子
        blockNum = 0;
        //检查上方
        if (currentY > 1 && MazeMap[currentX, currentY - 2] == Block)
        {
            blockPos[blockNum] = 0;
            blockNum++;
        }
        //检查右侧
        if (currentX < widthLimit && MazeMap[currentX + 2, currentY] == Block)
        {
            blockPos[blockNum] = 1;
            blockNum++;
        }
        //检查下方
        if (currentY < heightLimit && MazeMap[currentX, currentY + 2] == Block)
        {
            blockPos[blockNum] = 2;
            blockNum++;
        }
        //检查左侧
        if (currentX > 1 && MazeMap[currentX - 2, currentY] == Block)
        {
            blockPos[blockNum] = 3;
            blockNum++;
        }

        //选出下一个当前格
        if (blockNum > 0)
        {
            //随机选择一个邻格
            blockNum = _r.Next(0, blockNum);
            //把当前格入栈
            PathStack.Push(new Point(currentX, currentY));
            //连通邻格,并将邻格指定为当前格
            switch (blockPos[blockNum])
            {
                case 0:
                    MazeMap[currentX, currentY - 1] = UnBlock;
                    CreateScript.Add(new ScriptPoint(new Point(currentX, currentY - 1), false));
                    currentY -= 2;
                    break;
                case 1:
                    MazeMap[currentX + 1, currentY] = UnBlock;
                    CreateScript.Add(new ScriptPoint(new Point(currentX + 1, currentY), false));
                    currentX += 2;
                    break;
                case 2:
                    MazeMap[currentX, currentY + 1] = UnBlock;
                    CreateScript.Add(new ScriptPoint(new Point(currentX, currentY + 1), false));
                    currentY += 2;
                    break;
                case 3:
                    MazeMap[currentX - 1, currentY] = UnBlock;
                    CreateScript.Add(new ScriptPoint(new Point(currentX - 1, currentY), false));
                    currentX -= 2;
                    break;

            }
            //标记当前格
            MazeMap[currentX, currentY] = UnBlock;
            CreateScript.Add(new ScriptPoint(new Point(currentX, currentY), false));
        }
        else if (PathStack.Count > 0)
        {
            //将栈顶作为当前格
            Point top = PathStack.Pop();
            currentY = top.Y;
            currentX = top.X;
        }
    } while (PathStack.Count > 0);
}

上一篇:Js添加消息提示数量
下一篇:php中trait(性状)与generator(生成器)

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。

好贷网好贷款