private MazeGridpoint SearchForSolution(Queue <MazeGridpoint> queueToSolveMaze)
        {
            // As long as there are still elements in the queue to check, keep going
            while (queueToSolveMaze.Any())
            {
                var currentMazeGridpoint = queueToSolveMaze.Dequeue();
                currentMazeGridpoint.HasBeenVisited = true;
                MazeToSolve.NotifyMazeHasBeenUpdated();
                MazeToSolve.NotifyMazeToBeRedrawnUpdated();

                _foundMazeFinishPoint = MazeToSolve.CheckIfAtFinish(currentMazeGridpoint);

                // Quit now if the end of the maze was found
                if (_foundMazeFinishPoint)
                {
                    return(currentMazeGridpoint);
                }

                // Investigate each direction available at the current gridpoint
                foreach (var direction in currentMazeGridpoint.DirectionsAvailable.OpenPaths)
                {
                    if (!MazeToSolve.IsValidPositionInMaze(currentMazeGridpoint, direction))
                    {
                        continue;
                    }

                    var nextMazeGridpoint = MazeToSolve.ProceedToNewGridpoint(currentMazeGridpoint, direction);

                    if (MazeToSolve.CheckIfAtDeadEnd(nextMazeGridpoint) || nextMazeGridpoint.HasBeenVisited)
                    {
                        continue;
                    }

                    // Set up the parent gridpoint for each direction that is valid
                    var nextMazeSolutionElement = PathToSolveMaze.Single(m => m.MazeGridpoint == nextMazeGridpoint);
                    nextMazeSolutionElement.ParentMazeGridpoint = currentMazeGridpoint;

                    nextMazeGridpoint.HasBeenVisited = true;

                    // Make sure we haven't found the end of the maze for each direction
                    _foundMazeFinishPoint = MazeToSolve.CheckIfAtFinish(nextMazeGridpoint);

                    if (_foundMazeFinishPoint)
                    {
                        return(nextMazeGridpoint);
                    }

                    // If its not the end of the maze, queue it up for another round down the line
                    queueToSolveMaze.Enqueue(nextMazeGridpoint);

                    Console.WriteLine("X : " + nextMazeGridpoint.Position.X + ", Y : " + nextMazeGridpoint.Position.Y + " Direction : " + direction);
                }
            }

            throw new Exception("Maze Solver Error: Sorry, maze could not be solved. The maze image provided may be invalid.");
        }
Пример #2
0
        private void RecursivelySearchForSolution(MazeGridpoint currentMazeGridpoint, MazeSolutionElementTree parentMazeSolutionElementTree)
        {
            // No need to keep going on this call if the finish has already been found
            if (_foundMazeFinishPoint)
            {
                return;
            }

            _mazeSolutionElementTree = parentMazeSolutionElementTree;
            _foundMazeFinishPoint    = MazeToSolve.CheckIfAtFinish(currentMazeGridpoint);

            currentMazeGridpoint.HasBeenVisited = true;
            MazeToSolve.NotifyMazeHasBeenUpdated();
            MazeToSolve.NotifyMazeToBeRedrawnUpdated();

            // Now that we've checked the current gridpoint, let's make sure we need to do more work
            if (_foundMazeFinishPoint)
            {
                return;
            }

            // For each direction available that is valid, add an element to the tree and recursively
            // call the search function again.
            foreach (var direction in currentMazeGridpoint.DirectionsAvailable.OpenPaths)
            {
                if (!MazeToSolve.IsValidPositionInMaze(currentMazeGridpoint, direction))
                {
                    continue;
                }

                var nextMazeGridpoint = MazeToSolve.ProceedToNewGridpoint(currentMazeGridpoint, direction);

                if (MazeToSolve.CheckIfAtDeadEnd(nextMazeGridpoint) || nextMazeGridpoint.HasBeenVisited)
                {
                    continue;
                }

                var nextMazeSolutionElement = new MazeSolutionElementTree
                {
                    ParentSolutionElement = parentMazeSolutionElementTree,
                    MazeGridpoint         = nextMazeGridpoint
                };

                Console.WriteLine("X : " + nextMazeGridpoint.Position.X + ", Y : " + nextMazeGridpoint.Position.Y + " Direction : " + direction);
                RecursivelySearchForSolution(nextMazeGridpoint, nextMazeSolutionElement);
            }
        }
        /// <summary>
        /// Solves the maze using a brute force algorithm approach.
        /// </summary>
        public override void SolveMaze()
        {
            // Apply all pre-treament logics, if any
            PreTreatmentLogics.ForEach(p => p.PreTreatMazeToSolve());

            // Set all parent gridpoints to null at the start
            var currentMazeGridpoint = MazeToSolve.MazeGridpoints.Values.First(m => m.IsStartPoint && m.DirectionsAvailable.Count > 0);

            // Keep on looking so long as we haven't reached the finish
            while (!MazeToSolve.CheckIfAtFinish(currentMazeGridpoint))
            {
                currentMazeGridpoint.HasBeenVisited = true;

                // Picked a direction and go in that direction
                var directionToProceed = DirectionPickerLogic.PickDirectionToProceed(PathToSolveMaze, currentMazeGridpoint);

                if (directionToProceed == DirectionEnum.None)
                {
                    throw new Exception("Maze Solver Error: Sorry, maze could not be solved. The maze image provided may be invalid.");
                }

                currentMazeGridpoint = DetermineNextMazeGridPoint(currentMazeGridpoint, directionToProceed);

                Console.WriteLine("X : " + currentMazeGridpoint.Position.X + ", Y : " + currentMazeGridpoint.Position.Y + " Direction : " + directionToProceed);
                MazeToSolve.NotifyMazeHasBeenUpdated();
                MazeToSolve.NotifyMazeToBeRedrawnUpdated();
            }

            // Once out of the loop, the current gridpoint will be the final gridpoint
            var finalMazeSolutionElement = new MazeSolutionElement
            {
                StepNumber         = PathToSolveMaze.Count,
                MazeGridpoint      = currentMazeGridpoint,
                DirectionProceeded = DirectionEnum.None
            };

            PathToSolveMaze.Add(finalMazeSolutionElement);
        }