2010-04-06 5 views
2

J'essaie de créer un labyrinthe-générateur, et pour cela j'ai implémenté l'Algorithme de Primized Randonnée en C#.Rendu d'un labyrinthe généré de manière aléatoire dans WinForms.NET

Cependant, le résultat de la génération n'est pas valide. Je n'arrive pas à déterminer si c'est mon rendu ou si l'implémentation est invalide. Donc, pour commencer, j'aimerais que quelqu'un jette un coup d'oeil à la mise en œuvre:

Le labyrinthe est une matrice de cellules.

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

Voici un exemple sur le résultat rendu:

Rendered Maze http://dl.dropbox.com/u/1744224/Upload/primrecur.png

Modifier Ok, permet de jeter un oeil à la partie de rendu alors:

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

Et je suppose que, Pour comprendre cela, nous devons voir la classe MazeCell et 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

Impossible de trouver un problème avec l'algorithme. Le problème doit être ailleurs ... –

Répondre

2

Ceci est juste une pensée:

Même si vous ne l'avez pas affiché le code où vous ajoutez des murs à une cellule, je crois que l'erreur est logique. Une cellule unique a 4 murs mais deux cellules contiguës ont seulement 7 murs. Non 8.

Vous devez également retirer le mur correspondant de l'autre cellule lors du retrait de la fonction randomWall. Pour développer un peu plus en détail: Si votre algorithme AddWallsToMaze ajoute 4 murs à chaque cellule, il y a des murs en double.

Ex:
CellA a une paroi avec CellB. Appelons-le Wall1.
CellB a un mur avec CellA. C'est Wall2 NOT Wall1.
Cela devrait être Wall1.

+0

Bonne prise Sani. Ce que vous avez suggéré était le même problème que je suis tombé lorsque j'ai essayé d'utiliser le code ci-dessus pour ajouter des murs. L'implémentation de l'addwall de la classe MazeCell doit vérifier si le mur a déjà été ajouté à partir de l'autre cellule (le paramètre "MazeCell b"). Je pense que c'est ta réponse Claus. – Audie

+0

Hmm, bien. C'est la même référence qui est ajoutée, et je ne fais que sortir les murs non-passage (notez le lambda), mais je vais y jeter un coup d'oeil. –

0

La solution était de corriger l'erreur de rendu dans la façon dont les cellules ont été dessinées. Je faisais juste les murs du fond, et le rendu a laissé & murs supérieurs.

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

Je ne suis pas parfaitement satisfait du résultat. Je pense que je vais essayer un autre algorihm, cela ne semble pas aussi bien formé que j'avais espéré.

Questions connexes