Beispiel #1
0
        public void BuildMaze(int l, int h)
        {
            this.l = l;
            this.h = h;

            this.totalCells = l * h;
            this.cells      = new Cellule[totalCells];

            Stack <Cellule> cellsStack = new Stack <Cellule>(); // Le stack des cellules

            int x = 0;
            int y = 0;

            for (int i = 0; i < this.totalCells; i++) // Ajoute les cellules dans la liste de toutes les cellules (pas le stack)
            {
                this.cells[i] = new Cellule(x, y, i);
                x++;
                if (x == l)
                {
                    x = 0;
                    y++;
                }
            }


            Random  rnd         = new Random();
            int     rndKey      = rnd.Next(0, this.totalCells);
            Cellule currentCell = this.cells[rndKey]; // Cellule aléatoire pour initialiser la génération du labyrinthe

            int visitedCells = 1;                     // Nombre de cellules visitées au début de la génération


            // Tant qu'on n'a pas visité toutes les cellules
            while (visitedCells < this.totalCells)
            {
                currentCell.visited = true;

                // neighbours va contenir toutes les cellules voisines visitables
                List <Cellule> neighbours = new List <Cellule>();
                if (currentCell.x > 0)                                   // Si on n'est pas sur le bord gauche
                {
                    if (!(this.cells[currentCell.key - 1]).visited)      // Si la cellule sur la gauche n'a pas déjà été visitée
                    {
                        neighbours.Add(this.cells[currentCell.key - 1]); // On ajoute la cellule de gauche à la liste des voisins visitables
                    }
                }
                if (currentCell.x + 1 < l)                          // Si on n'est pas sur le bord droit
                {
                    if (!(this.cells[currentCell.key + 1]).visited) // Si la cellule à droite n'a pas déjà été visitée
                    {
                        neighbours.Add(this.cells[currentCell.key + 1]);
                    }
                }
                if (currentCell.y > 0)                              // Si on n'est pas sur le bord du haut
                {
                    if (!(this.cells[currentCell.key - l]).visited) // Si la cellule juste en haut n'a pas déjà été visitée
                    {
                        neighbours.Add(this.cells[currentCell.key - l]);
                    }
                }
                if (currentCell.y + 1 < h)                        // Si on n'est pas sur le bord du bas
                {
                    if (!this.cells[currentCell.key + l].visited) // Si la cellule juste en bas n'a pas déjà été visitée
                    {
                        neighbours.Add(this.cells[currentCell.key + l]);
                    }
                }

                // Si on n'est pas bloqué :
                if (neighbours.Count > 0)
                {
                    // Sélectionner une cellule au hasard
                    int     r       = rnd.Next(neighbours.Count);
                    Cellule newCell = neighbours[r];

                    // Abbattre les murs
                    if (newCell.key == currentCell.key - 1)
                    {
                        currentCell.border[3] = false;           // On abbat la bordure ouest de la cellule courante
                        newCell.border[1]     = false;           // On abbat la bordure est de la cellule voisine de gauche
                    }
                    else if (newCell.key == currentCell.key + 1) // Pareil qu'au dessus mais pour la cellule à droite
                    {
                        currentCell.border[1] = false;
                        newCell.border[3]     = false;
                    }
                    else if (newCell.key == currentCell.key - l) // Pour la cellule en haut
                    {
                        currentCell.border[0] = false;
                        newCell.border[2]     = false;
                    }
                    else if (newCell.key == currentCell.key + l) // Pour la cellule en bas
                    {
                        currentCell.border[2] = false;
                        newCell.border[0]     = false;
                    }

                    // Ajout de currentCell dans le stack
                    cellsStack.Push(currentCell);

                    currentCell = newCell;
                    visitedCells++;
                }
                else // Si on se retrouve bloqué...
                {
                    currentCell = cellsStack.Pop(); // ... On dépile
                }
            }

            // Points d'entrée et de sortie aléatoires
            this.start  = rnd.Next(0, this.totalCells);
            this.finish = rnd.Next(0, this.totalCells);
        }
Beispiel #2
0
        private void DrawMaze()
        {
            System.Drawing.Graphics graphicsObj;

            graphicsObj = this.CreateGraphics();

            this.maze.BuildMaze(l, h);

            // On initialise les crayons (grid = les bordures des cellules, border = la bordure du labyrinthe)
            Pen grid   = new Pen(System.Drawing.Color.Black, 1);
            Pen border = new Pen(System.Drawing.Color.Black, 3);

            // Le labyrinthe sera placé au dessus d'une zone blanche des mêmes dimensions
            SolidBrush canvas = new SolidBrush(System.Drawing.Color.White);
            Graphics   gr;

            gr = this.CreateGraphics();
            Rectangle rCanvas = new Rectangle(0, 0 + this.marginTop, this.l * this.dim, this.h * this.dim);

            gr.FillRectangle(canvas, rCanvas);
            canvas.Dispose();
            gr.Dispose();

            // Les bordures du labyrinthe
            graphicsObj.DrawRectangle(border, 0, 0 + this.marginTop, this.l * this.dim, this.h * this.dim);



            int line = 0; // La ligne actuellement parcourue
            int cell = 0; // La colone actuellement parcourue

            // On parcourt chacune des cellules du labyrinthe
            for (int i = 1; i < this.maze.totalCells; i++)
            {
                // On dessine successivement chacune des bordures de la cellule courante
                Cellule currentCell = this.maze.cells[i - 1];
                if (currentCell.border[0])
                {
                    graphicsObj.DrawLine(grid, cell * this.dim, line * this.dim + this.marginTop, cell * this.dim + this.dim, line * this.dim + this.marginTop);
                }
                if (currentCell.border[1])
                {
                    graphicsObj.DrawLine(grid, cell * this.dim + this.dim, line * this.dim + this.marginTop, cell * this.dim + this.dim, line * this.dim + this.dim + this.marginTop);
                }
                if (currentCell.border[2])
                {
                    graphicsObj.DrawLine(grid, cell * this.dim, line * this.dim + this.dim + this.marginTop, cell * this.dim, line * this.dim + this.dim + this.marginTop);
                }
                if (currentCell.border[3])
                {
                    graphicsObj.DrawLine(grid, cell * this.dim, line * this.dim + this.marginTop, cell * this.dim, line * this.dim + this.dim + this.marginTop);
                }

                // Si la cellule courante se trouve être le point d'entrée, on dessine un carré vert
                if (this.maze.start == i - 1)
                {
                    SolidBrush start = new SolidBrush(System.Drawing.Color.Green);
                    Graphics   formGraphics;
                    formGraphics = this.CreateGraphics();
                    Rectangle r = new Rectangle(cell * this.dim + 2, line * this.dim + 2 + this.marginTop, this.dim - 3, this.dim - 3);
                    formGraphics.FillRectangle(start, r);
                    start.Dispose();
                    formGraphics.Dispose();
                }

                // Si la cellule courante se trouve être le point d'entrée, on dessine un carré rouge dedans
                if (this.maze.finish == i - 1)
                {
                    SolidBrush finish = new SolidBrush(System.Drawing.Color.Red);
                    Graphics   formGraphics;
                    formGraphics = this.CreateGraphics();
                    Rectangle r = new Rectangle(cell * this.dim + 2, line * this.dim + 2 + this.marginTop, this.dim - 3, this.dim - 3);
                    formGraphics.FillRectangle(finish, r);
                    finish.Dispose();
                    formGraphics.Dispose();
                }

                cell++;              // Fin de l'itération, on passe à la colone suivante

                if (i % this.l == 0) // Si on arrive à la fin de la ligne
                {
                    line++;
                    cell = 0;
                }
            }
        }
Beispiel #3
0
        // Pour résoudre le labyrinthe
        public List <int> solve()
        {
            // Le stack contenant toutes les cellules visitées.
            // A la fin de l'exécution, ne contiendra que les cases faisant partie du chemin
            Stack <Cellule> visitedCells = new Stack <Cellule>();

            Cellule currentCell = cells[this.start];

            visitedCells.Push(currentCell);                   // On commence par placer la cellule de départ dans le stack

            List <Cellule> neighbours = new List <Cellule>(); // Contiendra tous les voisins parcourables au fur et à mesure du parcours des cellules

            while (currentCell.key != this.finish)            // Tant qu'on est pas arrivé à la sortie...
            {
                currentCell.visitedSolve = true;              // On note qu'on a visité la cellule courante

                // NORTH ... Si la cellule nord peut être visitée...
                if (!currentCell.border[0] && !this.cells[currentCell.key - l].border[2] && !this.cells[currentCell.key - l].visitedSolve)
                {
                    neighbours.Add(this.cells[currentCell.key - l]); // On la rajoute à neighbours
                }

                // Et ainsi de suite

                // EST
                if (!currentCell.border[1] && !this.cells[currentCell.key + 1].border[3] && !this.cells[currentCell.key + 1].visitedSolve)
                {
                    neighbours.Add(this.cells[currentCell.key + 1]);
                }


                // SOUTH
                if (!currentCell.border[2] && !this.cells[currentCell.key + l].border[0] && !this.cells[currentCell.key + l].visitedSolve)
                {
                    neighbours.Add(this.cells[currentCell.key + l]);
                }


                // WEST
                if (!currentCell.border[3] && !this.cells[currentCell.key - 1].border[1] && !this.cells[currentCell.key - 1].visitedSolve)
                {
                    neighbours.Add(this.cells[currentCell.key - 1]);
                }


                Random rnd = new Random();
                if (neighbours.Count > 0) // Si neighbours contient des cellules...
                {
                    visitedCells.Push(currentCell);
                    currentCell = neighbours[rnd.Next(0, neighbours.Count)]; // On en sélectionne une au hasard
                }
                else
                {
                    currentCell = visitedCells.Pop(); // Sinon on fait demi tour car on est bloqué
                }
                neighbours.Clear();                   // Réinitialisation pour le tour suivant
            }

            List <int> solution = new List <int>();

            // On place les indexes de toutes les cellules faisant partie du chemin final dans une liste
            foreach (var current in visitedCells)
            {
                solution.Insert(0, current.key);
            }

            return(solution);
        }