2010-04-06 4 views
2

미로 생성기를 만들려고합니다.이를 위해 C#에서 랜덤 화 된 Prim 알고리즘을 구현했습니다.WinForms.NET에서 무작위로 생성 된 미로 렌더링

그러나 생성 결과가 유효하지 않습니다. 내 렌더링인지 유효하지 않은 구현인지 알 수 없습니다. 처음에는 누군가 구현을 살펴 보도록하겠습니다.

maze는 세포 매트릭스입니다.

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 
    } 
} 
+0

알고리즘에 문제가없는 것 같습니다. 문제는 다른 곳에 있어야합니다 ... –

답변

2

: 당신은 당신이 셀에 벽을 추가하는 코드를 게시하지 않은 경우에도

, 그 논리 오류라고 생각. 단일 셀에는 4 개의 벽이 있지만 인접한 셀에는 7 개의 벽만 있습니다. 그렇지 않습니다. 8.

randomWall을 제거 할 때 다른 셀에서도 해당 벽을 제거해야합니다.

좀 더 자세하게 설명하십시오 : AddWallsToMaze 알고리즘이 각 셀에 4 개의 벽을 추가하면 벽이 중복됩니다.

예 :
CellA에는 CellB가있는 벽이 있습니다. Wall1이라고합시다.
CellB에는 CellA가있는 벽이 있습니다. 이것은 Wall2가 아닌 Wall1입니다.
Wall1이어야합니다.

+0

좋은 잡기 Sani. 당신이 제안한 것은 벽을 추가하기 위해 위의 코드를 사용하려고했을 때와 같은 문제였습니다. MazeCell 클래스의 addwall을 구현하려면 벽이 이미 다른 셀 ("MazeCell b"매개 변수)에서 추가되었는지 확인해야합니다. 나는 이것이 당신의 대답 클로스라고 생각합니다. – Audie

+0

음, 음. 그것은 추가 된 동일한 참고 자료이며, 나는 단지 통로가 아닌 벽을 꺼내고 있습니다 (람다에 주목하십시오). 그러나 나는 그것을 조사 할 것입니다. –

0

해결 방법은 셀이 그려지는 방식에서 렌더링 실수를 수정하는 것이 었습니다. 나는 오른쪽 벽을 & 밑에서하고 있었고 왼쪽 벽면은 &의 위쪽 벽을 렌더링하고 있었다.

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 
     ); 
    } 
} 

결과에 만족하지 않습니다. 나는 다른 알고리즘을 시도 할 것이라고 생각하는데, 이것은 내가 원하는만큼 잘 형성되지 않은 것처럼 보입니다.