Example #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;
                }
            }
        }