Ejemplo n.º 1
0
        /// <summary>
        /// Returns an enumerator that solves the maze by creating a solution path using the WallFollower Algorithm
        /// </summary>
        /// <param name="service"></param>
        public override IEnumerator SolveMazeRoutine(MazeSolvingService service)
        {
            //set starting point
            MazeCell walker = service.EntranceCell;

            walker.MarkAsPartOfSolution();

            //store direction for manipulation
            Vector2Int direction = Vector2Int.left;

            //loop until exit has been reached by the walker
            MazeCell exitCell = service.ExitCell;

            while (walker != exitCell)
            {
                //try first walking left and then walking forward. Rotate right if both fail
                MazeCell nextCellInPath = null;
                if (service.GetNextCellInPathRelative(walker, GetValueRotatedLeft(direction), ref nextCellInPath))
                {
                    //if we can walk left, first rotate left
                    Rotate(ANGLE_LEFT, ref direction);

                    //make the next cell in the path and the passage towards it part of the solution
                    nextCellInPath.MarkAsPartOfSolution();
                    nextCellInPath.MarkWallAsPartOfSolution(walker);
                    walker.MarkWallAsPartOfSolution(nextCellInPath);
                }
                else if (service.GetNextCellInPathRelative(walker, direction, ref nextCellInPath))
                {
                    //make the next cell in the path and the passage towards it part of the solution
                    nextCellInPath.MarkAsPartOfSolution();
                    nextCellInPath.MarkWallAsPartOfSolution(walker);
                    walker.MarkWallAsPartOfSolution(nextCellInPath);
                }
                else
                {
                    //rotate right to look for a new way to walk left or forward
                    Rotate(ANGLE_RIGHT, ref direction);
                }

                if (nextCellInPath != null)
                {
                    //if the next cell in the path was found, we can walk on from it
                    walker = nextCellInPath;

                    if (service.DebugMode)
                    {
                        walker.SetDirectionArrow(direction);
                        walker.ShowDirectionArrow(true);
                    }
                }

                yield return(null);
            }

            CompletedRoutine();
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns an enumerator that solves the maze by creating a solution path using the Recursive Backtracking Algorithm
        /// </summary>
        /// <param name="service"></param>
        public override IEnumerator SolveMazeRoutine(MazeSolvingService service)
        {
            //create datastructues necessary for algorithm to work
            Stack <MazeCell> stack = new Stack <MazeCell>();

            //set starting point and store exit for loop condition
            MazeCell exitCell = service.ExitCell;
            MazeCell entrance = service.EntranceCell;

            entrance.MarkAsPartOfSolution();
            stack.Push(entrance);

            //loop until the next cell in path is the exit
            MazeCell nextCellInPath = null;

            while (nextCellInPath != exitCell)
            {
                //look at the cell at the top of the stack and get the next cells in the path relative to it
                MazeCell        cell            = stack.Peek();
                List <MazeCell> cellsNextInPath = service.GetNextCellsInPath(cell);

                //check if the path is a dead end or not
                if (cellsNextInPath.Count > 0)
                {
                    //fetch a random cell that is next in the path and mark it as part of the solution
                    nextCellInPath = cellsNextInPath[Random.Range(0, cellsNextInPath.Count)];
                    nextCellInPath.MarkAsPartOfSolution();

                    //mark the walls as part of the solution aswell
                    cell.MarkWallAsPartOfSolution(nextCellInPath);
                    nextCellInPath.MarkWallAsPartOfSolution(cell);

                    //push the next cell to the stack
                    stack.Push(nextCellInPath);
                }
                else
                {
                    //mark the dead end and its broken walls as checked, so not part of the solution anymore
                    cell.MarkAsChecked();
                    cell.MarkBrokenWallsAsChecked();

                    //pop the stack to backtrack
                    stack.Pop();
                }

                yield return(null);
            }

            CompletedRoutine();
        }
        /// <summary>
        /// Returns an enumerator that solves the maze by creating a solution path using the DeadEndFilling Algorithm
        /// </summary>
        /// <param name="service"></param>
        public override IEnumerator SolveMazeRoutine(MazeSolvingService service)
        {
            //fill dead ends of the maze until junktions are found
            IEnumerable <MazeCell> deadEnds = service.Cells.Cast <MazeCell>().Where(cell => cell.IsDeadEnd);

            foreach (MazeCell deadEnd in deadEnds)
            {
                yield return(CheckUntilJunctionRoutine(deadEnd, service));
            }

            //start walking from the entrance
            MazeCell walker = service.EntranceCell;

            walker.MarkAsPartOfSolution();
            yield return(null);

            //loop until the walker is at the exit
            MazeCell exitCell = service.ExitCell;

            while (walker != exitCell)
            {
                //get the next cell that is on current path
                List <MazeCell> nextCellsInPath = service.GetNextCellsInPath(walker);
                if (nextCellsInPath.Count == 1)
                {
                    //make the cell part of the path solution
                    MazeCell nextCellInPath = nextCellsInPath[0];
                    nextCellInPath.MarkAsPartOfSolution();

                    //mark its walls as part of the solution aswell
                    walker.MarkWallAsPartOfSolution(nextCellInPath);
                    nextCellInPath.MarkWallAsPartOfSolution(walker);

                    //the next cell in the path is now the walker
                    walker = nextCellInPath;
                }
                else
                {
                    throw new System.InvalidOperationException($"The solution path could not be created from {walker.name} with {nextCellsInPath.Count} next cells in path :: this is unintended behaviour!");
                }

                yield return(null);
            }

            CompletedRoutine();
        }
        /// <summary>
        /// Returns an enumerator that marks the maze as checked from given walker cell until a junction is met
        /// </summary>
        /// <param name="walker"></param>
        /// <param name="service"></param>
        /// <returns></returns>
        private IEnumerator CheckUntilJunctionRoutine(MazeCell walker, MazeSolvingService service)
        {
            walker.MarkAsChecked();
            yield return(null);

            //loop until a junction is found and is borken out of the loop
            while (true)
            {
                //get the next cell in the current path
                List <MazeCell> cellsNextInPath = service.GetNextCellsInPath(walker);
                if (cellsNextInPath.Count == 1)
                {
                    //save it is a junction
                    MazeCell nextCellInPath = cellsNextInPath[0];
                    bool     isJunction     = nextCellInPath.IsJunction;

                    //mark the walls as checked
                    walker.MarkWallAsChecked(nextCellInPath);
                    nextCellInPath.MarkWallAsChecked(walker);

                    if (isJunction)
                    {
                        //if the cell was a junction, break out of the loop
                        break;
                    }
                    else
                    {
                        //if the cell wasn't a junction, mark the cell as checked and continue from it
                        nextCellInPath.MarkAsChecked();
                        walker = nextCellInPath;
                    }
                }
                else
                {
                    throw new System.InvalidOperationException($"Filling in until junktion failed :: there should be one next cell in {walker}'s path each time");
                }

                yield return(null);
            }
        }
Ejemplo n.º 5
0
 public abstract void SolveMaze(MazeSolvingService service);
Ejemplo n.º 6
0
 public abstract IEnumerator SolveMazeRoutine(MazeSolvingService service);