Пример #1
0
        /// <summary>
        /// Creates a maze by linking cells using Eller's algorithm
        /// </summary>
        /// <param name="service"></param>
        public override void CreateMaze(MazeGenerationService service)
        {
            //create data structures necessary for algorithm to work
            MazeCell[,] gridcells = service.Cells;
            MazeCell[] cells = gridcells.Cast <MazeCell>().ToArray();

            //assign maze cells their set numbers
            AssignSetNumbers(gridcells, service.DebugMode);

            for (int y = 0; y < gridcells.GetLength(1); y++)
            {
                for (int x = 0; x < gridcells.GetLength(0); x++)
                {
                    //mark cell as visited
                    MazeCell cell = gridcells[x, y];
                    cell.MarkAsVisited();

                    List <MazeCell> neighbours = service.GetNeighboursNotPartOfSet(cell);
                    if (neighbours.Count > 0)
                    {
                        //pick a random neighbour not part of the cells set and create passage between cell and neighbour
                        MazeCell randomNeighbour = neighbours[Random.Range(0, neighbours.Count)];
                        randomNeighbour.CreatePassage(cell);
                        cell.CreatePassage(randomNeighbour);

                        //all the cells belonging to the set the random neighbour belongs to are overtaken by the cell's set
                        MazeCell[] set = cells.Where(c => c.NumberValue == randomNeighbour.NumberValue).ToArray();
                        foreach (MazeCell overtakableCell in set)
                        {
                            overtakableCell.SetNumberValue(cell.NumberValue);
                        }
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        /// Returns an enumerator that creates a maze by linking cells using Kruskal's algorithm
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public override IEnumerator CreateMazeRoutine(MazeGenerationService service)
        {
            //assign each maze cell a number indicating which set it belongs to
            AssignSetNumbers(service.Cells, service.DebugMode);

            //create data structures necessary for algorithm to work
            MazeCell[]      cells = service.Cells.Cast <MazeCell>().ToArray();
            List <MazeCell> bag   = new List <MazeCell>(cells);

            //loop while bag is not not empty
            while (bag.Count != 0)
            {
                //pick a random cell and mark it as visited
                MazeCell randomCell = bag[Random.Range(0, bag.Count)];
                randomCell.MarkAsVisited();

                //fetch the neigbours of this cell that are not part of the same set
                List <MazeCell> neighbours = service.GetNeighboursNotPartOfSet(randomCell);

                if (neighbours.Count > 0)
                {
                    //pick a random neighbour and mark it as visited
                    MazeCell randomNeighbour = neighbours[Random.Range(0, neighbours.Count)];
                    randomNeighbour.MarkAsVisited();

                    //link the random neighbour with the random cell
                    randomNeighbour.CreatePassage(randomCell);
                    randomCell.CreatePassage(randomNeighbour);

                    //all the cells belonging to the set the random neighbour belongs to are overtaken by the random cell's set
                    MazeCell[] set = cells.Where(c => c.NumberValue == randomNeighbour.NumberValue).ToArray();
                    foreach (MazeCell overtakableCell in set)
                    {
                        overtakableCell.SetNumberValue(randomCell.NumberValue);
                    }
                }
                else
                {
                    //if all neighbours of the cel are part of the same set, remove the cell from the bag
                    bag.Remove(randomCell);
                }

                yield return(null);
            }

            CompletedRoutine();
        }