在WinForms.NET中渲染一个随机生成的迷宫
我试图创建一个迷宫生成器,为此我在C#中实现了随机Prim的算法。在WinForms.NET中渲染一个随机生成的迷宫
但是,生成的结果是无效的。我无法弄清楚它是我的渲染还是无效的实现。因此,对于初学者,我希望有人看看执行:
迷宫是一个单元矩阵。
var cell = maze[0, 0];
cell.Connected = true;
var walls = new HashSet<MazeWall>(cell.Walls);
while (walls.Count > 0)
{
var randomWall = walls.GetRandom();
var randomCell = randomWall.A.Connected ? randomWall.B : randomWall.A;
if (!randomCell.Connected)
{
randomWall.IsPassage = true;
randomCell.Connected = true;
foreach (var wall in randomCell.Walls)
walls.Add(wall);
}
walls.Remove(randomWall);
}
这里有一个例子在渲染结果:
Rendered Maze http://dl.dropbox.com/u/1744224/Upload/primrecur.png
编辑好吧,让我们看看渲染部分则:
private void MazePanel_Paint(object sender, PaintEventArgs e)
{
int size = 20;
int cellSize = 10;
MazeCell[,] maze = RandomizedPrimsGenerator.Generate(size);
mazePanel.Size = new Size(
size * cellSize + 1,
size * cellSize + 1
);
e.Graphics.DrawRectangle(Pens.Blue, 0, 0,
size * cellSize,
size * cellSize
);
for (int y = 0; y < size; y++)
for (int x = 0; x < size; x++)
{
foreach(var wall in maze[x, y].Walls.Where(w => !w.IsPassage))
{
if (wall.Direction == MazeWallOrientation.Horisontal)
{
e.Graphics.DrawLine(Pens.Blue,
x * cellSize, y * cellSize,
x * cellSize + cellSize,
y * cellSize
);
}
else
{
e.Graphics.DrawLine(Pens.Blue,
x * cellSize,
y * cellSize, x * cellSize,
y * cellSize + cellSize
);
}
}
}
}
我猜,要了解这一点,我们需要看到MazeCell和MazeWall类:
namespace MazeGenerator.Maze
{
class MazeCell
{
public int Column
{
get;
set;
}
public int Row
{
get;
set;
}
public bool Connected
{
get;
set;
}
private List<MazeWall> walls = new List<MazeWall>();
public List<MazeWall> Walls
{
get { return walls; }
set { walls = value; }
}
public MazeCell()
{
this.Connected = false;
}
public void AddWall(MazeCell b)
{
walls.Add(new MazeWall(this, b));
}
}
enum MazeWallOrientation
{
Horisontal,
Vertical,
Undefined
}
class MazeWall : IEquatable<MazeWall>
{
public IEnumerable<MazeCell> Cells
{
get
{
yield return CellA;
yield return CellB;
}
}
public MazeCell CellA
{
get;
set;
}
public MazeCell CellB
{
get;
set;
}
public bool IsPassage
{
get;
set;
}
public MazeWallOrientation Direction
{
get
{
if (CellA.Column == CellB.Column)
{
return MazeWallOrientation.Horisontal;
}
else if (CellA.Row == CellB.Row)
{
return MazeWallOrientation.Vertical;
}
else
{
return MazeWallOrientation.Undefined;
}
}
}
public MazeWall(MazeCell a, MazeCell b)
{
this.CellA = a;
this.CellB = b;
a.Walls.Add(this);
b.Walls.Add(this);
IsPassage = false;
}
#region IEquatable<MazeWall> Members
public bool Equals(MazeWall other)
{
return (this.CellA == other.CellA) && (this.CellB == other.CellB);
}
#endregion
}
}
这只是一个念头:
即使你没有张贴在您添加壁细胞的代码,我认为是逻辑上的错误。一个单元格有4个墙,但是两个相邻的单元格只有7个墙。不是8.
您需要从其他单元格中删除相应的墙以及删除随机墙。
详细说明: 如果您的AddWallsToMaze
算法为每个单元格添加4个墙,那么会有重复的墙。
例如:
CellA有一堵墙CellB。我们称之为Wall1。
CellB墙上有CellA。这是Wall2 NOT Wall1。
它应该是Wall1。
好赶上萨尼。你建议的是当我尝试使用上面的代码添加墙时碰到的同样的问题。 MazeCell类的addwall的实现需要检查墙是否已经从另一个单元添加(“MazeCell b”参数)。我认为这是你的答案克劳斯。 – Audie 2010-04-07 14:03:01
嗯,好吧。这与添加的参考文献是相同的,并且我只获取非通道墙(注意lambda),但我会研究它。 – 2010-04-07 23:14:35
解决的办法是纠正绘制细胞的渲染错误。我正在做&底部墙壁,并渲染左侧&顶部墙壁。
private static void RenderCell(PaintEventArgs e, int cellSize, int y, int x, MazeWall wall, Pen pen)
{
if (wall.Direction == MazeWallOrientation.Horisontal)
{
e.Graphics.DrawLine(pen,
x * cellSize,
y * cellSize + cellSize,
x * cellSize + cellSize,
y * cellSize + cellSize
);
}
else
{
e.Graphics.DrawLine(pen,
x * cellSize + cellSize,
y * cellSize,
x * cellSize + cellSize,
y * cellSize + cellSize
);
}
}
我对结果并不满意。我想我会尝试另一种算法,这看起来不像我希望的那么健全。
似乎无法找到算法的任何问题。问题必须在其他地方... – 2010-04-06 20:05:07