Exemple #1
0
        /// <summary>
        /// Executes a random walk from given unvisited cell adding visited cells to visited list on finish
        /// </summary>
        /// <param name="unvisitedCell"></param>
        /// <param name="service"></param>
        /// <param name="visited"></param>
        private void RandomWalk(MazeCell unvisitedCell, MazeGenerationService service, List <MazeCell> visited)
        {
            //setup data structures necessary for the random walk to take place
            List <KeyValuePair <MazeCell, Vector2Int> > records = new List <KeyValuePair <MazeCell, Vector2Int> >();
            List <MazeCell> neighbours = service.GetNeighbours(unvisitedCell);

            //pick a random neighbour as the walking position and check whether it is not already visited
            MazeCell walker = neighbours[Random.Range(0, neighbours.Count)];

            if (walker.IsVisited)
            {
                //mark the unvisited cell as visited
                unvisitedCell.MarkAsVisited();
                visited.Add(unvisitedCell);

                //link unvisited cell to the walker and return
                unvisitedCell.CreatePassage(walker);
                walker.CreatePassage(unvisitedCell);
                return;
            }

            //get the direction relative to the walker so we can store it as a record
            Vector2Int direction = unvisitedCell.GetDirectionRelative(walker);

            records.Add(new KeyValuePair <MazeCell, Vector2Int>(unvisitedCell, direction));

            //loop until there are not records left
            while (records.Count != 0)
            {
                //refresh the neighbours list with the walkers neighbours
                neighbours.Clear();
                neighbours.AddRange(service.GetNeighbours(walker));

                //pick a random neighbour, and record the direction from the walker to it
                MazeCell randomNeighbour = neighbours[Random.Range(0, neighbours.Count)];
                direction = walker.GetDirectionRelative(randomNeighbour);

                if (!records.TryUpdate(walker, direction))
                {
                    records.Add(new KeyValuePair <MazeCell, Vector2Int>(walker, direction));
                }

                if (randomNeighbour.IsVisited)
                {
                    //if the random neighbour is visited, carve out a path using the records and clear the records list
                    MarkRecordAsVisitedRecursive(records[0], records, service, visited);
                    records.Clear();
                }
                else
                {
                    //if the random neighbour isn't visited yet, set it as the new walker cell
                    walker = randomNeighbour;
                }
            }
        }
        /// <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();
        }
Exemple #3
0
        /// <summary>
        /// Returns an enumerator that creates a maze by linking cells using the adlous broder 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 startCell = service.RootCell;

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

            //set current cel as starting cell
            MazeCell currentCell = startCell;

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

            while (visited.Count != totalCells)
            {
                //pick a random neighbour of the current cell
                List <MazeCell> neighbours      = service.GetNeighbours(currentCell);
                MazeCell        randomNeighbour = neighbours[Random.Range(0, neighbours.Count)];

                if (!randomNeighbour.IsVisited)
                {
                    //if the random neighbour hasn't been visited yet, mark it as visited
                    randomNeighbour.MarkAsVisited();
                    visited.Add(randomNeighbour);

                    //create passage between cell and neighbour
                    randomNeighbour.CreatePassage(currentCell);
                    currentCell.CreatePassage(randomNeighbour);
                }

                //set current cell to random neighbour to travel from it
                currentCell = randomNeighbour;

                //show stepping feedback
                currentCell.ShowAsStep(true);
                yield return(null);

                currentCell.ShowAsStep(false);
            }

            CompletedRoutine();
        }