查看文章 |
因为最近要用C#开发一个走迷宫的小游戏,所以需要编写一个随机生成迷宫的组件,但是查阅了网上的很多相关资料,都不是很全。只知道最好的方法是采用图的遍历来做,但是依然不得要领。后来无意中看到了CodeZone上面的Generating Maze using C# and .NET(By Mike Gold September 25, 2002 ),才一下子明白过来,思路也清晰了。 这是Mike的程序的UML图—— ![]() 程序的核心在于遍历所有迷宫格子。Mike是这样写的: public void Generate() 我通过分析这个Generate()函数,再结合上方的UML,大致复原了Mike缩写程序的源代码。 简单的说,Mike这个程序的思路是这样的: 迷宫的格子当然是一个单独的类MazeCell,该对象除了拥有行、列两个坐标值外,还需要一个很重要的属性——墙,一个四个元素的INT型数组(private int[] wall = { 1, 1, 1, 1 };)。遍历迷宫的过程,就是拆墙的过程,数组的四个元素分别代表迷宫各自上、下、左、右四面墙的状态,拆哪面墙就将其置0以标志。相应的拆墙函数为KnockDownWall()。 迷宫格子的类写完了,相当于是基础已经搭建了起来。接下来就是核心的迷宫类,首先该对象必须用一个二维数组MazeCell[,] cells来装迷宫格子,然后需要一个堆栈Stack<MazeCell> mazeStack来装遍历过程中临时存储用的格子。 在最核心的遍历循环中,首先要从当前格子周围找一个四面墙都在的相邻格子(相邻是指的位于当前格子的上下左右),也就是未曾被访问的格子。这时可能得到以下几种结果: 1、有不止一个相邻的格子都未被访问过:这时需要生成一个随机数,挑选其中一个出来拆掉它与当前格子之间的墙并且压入堆栈,同时将其作为新的当前格子。 2、只有一个相邻的各自未被访问,这更方便,随机数都不用生成了,直接拿来拆墙,之后同上。 3、周围的格子都被访问过了,这说明当前格子已经走到了一条死路的尽头,所以需要把堆栈中的前一个格子Pop出来当作当前格子,再看看周围是否有路,如果还是没有就继续Pop直到能找到另外一条路。 该循环在访问完所有的格子后结束。此时,所有的格子都被拆掉了一面墙,迷宫也就生成了。 (数字表示程序遍历该迷宫的顺序)
![]()
接下来开始研究最短路径的问题……头疼…… |



