/// <summary>
        /// Returns an enumerator that creates a maze by linking cells using the HuntAndKill algorithm
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public override IEnumerator CreateMazeRoutine(MazeGenerationService service)
        {
            //create data structures necessary for algorithm to work
            List <MazeCell> visited = new List <MazeCell>();

            //set starting point
            MazeCell walker = service.RootCell;

            walker.MarkAsVisited();
            visited.Add(walker);

            //loop untill all cells have been visited
            long totalCells = service.Cells.LongLength;

            while (visited.Count != totalCells)
            {
                //check if the current walker has unvisited neighbours
                List <MazeCell> unvisitedNeighbours = service.GetUnVisitedNeighbours(walker);
                if (unvisitedNeighbours.Count > 0)
                {
                    //pick a random unvisited neighbour and mark it as visited
                    MazeCell randomUnvisitedNeighbour = unvisitedNeighbours[Random.Range(0, unvisitedNeighbours.Count)];
                    randomUnvisitedNeighbour.MarkAsVisited();
                    visited.Add(randomUnvisitedNeighbour);

                    //create passage between cell and neighbour
                    walker.CreatePassage(randomUnvisitedNeighbour);
                    randomUnvisitedNeighbour.CreatePassage(walker);

                    //the random unvisited neighbour is now the walker
                    walker = randomUnvisitedNeighbour;
                }
                else
                {
                    //scan the grid for a hunted cell that is unvisited but has visited neighbours and mark it as visited
                    MazeCell huntedCell = GetRandomUnVisitedCellWithVisitedNeighbours(service);
                    huntedCell.MarkAsVisited();
                    visited.Add(huntedCell);

                    //fetch one of its visited neighbours and link it with the hunted cell
                    List <MazeCell> visitedNeighbours      = service.GetVisitedNeighbours(huntedCell);
                    MazeCell        randomVisitedNeighbour = visitedNeighbours[Random.Range(0, visitedNeighbours.Count)];
                    huntedCell.CreatePassage(randomVisitedNeighbour);
                    randomVisitedNeighbour.CreatePassage(huntedCell);

                    //the hunted cell is now the walker
                    walker = huntedCell;
                }

                walker.ShowAsStep(true);
                yield return(null);

                walker.ShowAsStep(false);
            }

            CompletedRoutine();
        }
        /// <summary>
        /// Returns an enumerator that creates a maze by linking cells using the recursive backtracking algorithm
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public override IEnumerator CreateMazeRoutine(MazeGenerationService service)
        {
            //create data structures necessary for algorithm to work
            Stack <MazeCell> stack   = new Stack <MazeCell>();
            List <MazeCell>  visited = new List <MazeCell>();

            //set starting point
            MazeCell startCell = service.RootCell;

            startCell.MarkAsVisited();
            visited.Add(startCell);
            stack.Push(startCell);

            //loop until all cells have been visited
            long totalCells = service.Cells.LongLength;

            while (visited.Count != totalCells)
            {
                //pick the cell to branch from, from the top of the stack and retreive its neighbours
                MazeCell        newest     = stack.Peek();
                List <MazeCell> neighbours = service.GetUnVisitedNeighbours(newest);

                if (neighbours.Count > 0)
                {
                    //pick a random neighbour from the list
                    MazeCell neighbour = neighbours[Random.Range(0, neighbours.Count)];

                    //set it as visited and add it to the visited list
                    neighbour.MarkAsVisited();
                    visited.Add(neighbour);

                    //create passage between newest and neighbour
                    newest.CreatePassage(neighbour);
                    neighbour.CreatePassage(newest);

                    //push the neighbour to the stack
                    stack.Push(neighbour);
                }
                else
                {
                    //if no unvisited neighbours are available, backtrack by popping the stack
                    stack.Pop();
                }

                newest.ShowAsStep(true);
                yield return(null);

                newest.ShowAsStep(false);
            }

            CompletedRoutine();
        }
Exemple #3
0
        /// <summary>
        /// Returns an Enumerator that creates a maze by linking cells using the growing tree algorithm its prim version
        /// </summary>
        /// <param name="service"></param>
        public override IEnumerator CreateMazeRoutine(MazeGenerationService service)
        {
            //create data structures necessary for algorithm to work
            List <MazeCell> bag     = new List <MazeCell>();
            List <MazeCell> visited = new List <MazeCell>();

            //set starting point
            MazeCell startPoint = service.RootCell;

            startPoint.MarkAsVisited();
            visited.Add(startPoint);
            bag.Add(startPoint);

            //loop until all cells have been visited
            long totalCells = service.Cells.LongLength;

            while (visited.Count != totalCells)
            {
                //pick a random cell from the bag and check if it has unvisited neighbours
                MazeCell        randomCell          = bag[Random.Range(0, bag.Count)];
                List <MazeCell> unvisitedNeighbours = service.GetUnVisitedNeighbours(randomCell);
                if (unvisitedNeighbours.Count > 0)
                {
                    //pick a random unvisited neighbour and mark it as visited
                    MazeCell randomUnvisitedNeighbour = unvisitedNeighbours[Random.Range(0, unvisitedNeighbours.Count)];
                    randomUnvisitedNeighbour.MarkAsVisited();
                    visited.Add(randomUnvisitedNeighbour);

                    //create passage between cell and neighbour
                    randomCell.CreatePassage(randomUnvisitedNeighbour);
                    randomUnvisitedNeighbour.CreatePassage(randomCell);

                    //add the random unvisited neighbour to the bag
                    bag.Add(randomUnvisitedNeighbour);
                }
                else
                {
                    //if the cell doesn't have any unvisited neighbours, remove it from the bag
                    bag.Remove(randomCell);
                }

                randomCell.ShowAsStep(true);
                yield return(null);

                randomCell.ShowAsStep(false);
            }

            CompletedRoutine();
        }
        /// <summary>
        /// Returns an enumerator that creates a maze by linking cells using prim's algorithm
        /// </summary>
        /// <param name="service"></param>
        /// <returns></returns>
        public override IEnumerator CreateMazeRoutine(MazeGenerationService service)
        {
            //create data structures necessary for algorithm to work
            MazeCell[]      cells    = service.Cells.Cast <MazeCell>().ToArray();
            List <MazeCell> frontier = new List <MazeCell>();

            //set starting point
            MazeCell startCell = service.RootCell;

            startCell.MarkAsVisited();

            //add neighbours of starting cell to frontier
            frontier.AddRange(service.GetNeighbours(startCell));

            while (frontier.Count != 0)
            {
                //pick a random frontier cell, mark it as visited and remove it from the frontier
                MazeCell randomFrontierCell = frontier[Random.Range(0, frontier.Count)];
                randomFrontierCell.MarkAsVisited();
                frontier.Remove(randomFrontierCell);

                //pick a random visited neighbour of it and link it with it
                List <MazeCell> visitedNeighbours = service.GetVisitedNeighbours(randomFrontierCell);
                if (visitedNeighbours.Count > 0)
                {
                    MazeCell randomVisitedNeighbour = visitedNeighbours[Random.Range(0, visitedNeighbours.Count)];
                    randomFrontierCell.CreatePassage(randomVisitedNeighbour);
                    randomVisitedNeighbour.CreatePassage(randomFrontierCell);
                }

                //add unvisited neighbours of it to the frontier if they aren't already in it
                List <MazeCell> unvisitedNeighbours = service.GetUnVisitedNeighbours(randomFrontierCell);
                foreach (MazeCell cell in unvisitedNeighbours)
                {
                    if (!frontier.Contains(cell))
                    {
                        frontier.Add(cell);
                    }
                }

                randomFrontierCell.ShowAsStep(true);
                yield return(null);

                randomFrontierCell.ShowAsStep(false);
            }

            CompletedRoutine();
        }