public void PickDirectionToProceed_NoElementsInSolutionPath_PicksDirectionUp()
        {
            var currentMazeGridpoint =
                new MazeGridpoint(new CartesianCoordinate(2, 2), new DirectionsAvailable(), false, false, false);

            var listOfMazeGridpoints = new List <MazeGridpoint>
            {
                new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false),
                new MazeGridpoint(new CartesianCoordinate(0, 2), new DirectionsAvailable(), false, false, true),

                new MazeGridpoint(new CartesianCoordinate(1, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 2), new DirectionsAvailable(), false, false, false),

                currentMazeGridpoint,

                new MazeGridpoint(new CartesianCoordinate(3, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 3), new DirectionsAvailable(), false, false, false),

                new MazeGridpoint(new CartesianCoordinate(4, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 4), new DirectionsAvailable(), false, true, false)
            };

            var mazeToTest      = new Maze(listOfMazeGridpoints.ToDictionary(m => m.Position, m => m));
            var directionPicker = new WallHuggingDirectionPicker(mazeToTest);
            var mazeSolution    = new List <MazeSolutionElement>();

            var directionToProceed = directionPicker.PickDirectionToProceed(mazeSolution, currentMazeGridpoint);

            Assert.AreEqual(directionToProceed, DirectionEnum.Up);
        }
Esempio n. 2
0
        public void CheckIfAtDeadEnd_GridpointIsAtFinish_ReturnsFalse()
        {
            var mazeToTest    = GetTestMaze();
            var mazeGridpoint = new MazeGridpoint(new CartesianCoordinate(1, 1), new DirectionsAvailable(), false, true, false);

            Assert.IsFalse(mazeToTest.CheckIfAtDeadEnd(mazeGridpoint));
        }
Esempio n. 3
0
        public void IsValidPositionInMaze_DirectionStaysInsideOfMaze_ReturnsTrue()
        {
            var mazeToTest    = GetTestMaze();
            var mazeGridpoint = new MazeGridpoint(new CartesianCoordinate(1, 0), new DirectionsAvailable(), false, false, false);

            Assert.IsTrue(mazeToTest.IsValidPositionInMaze(mazeGridpoint, DirectionEnum.Down));
        }
Esempio n. 4
0
        public void ProceedToNewGridpoint_DirectionMovesOutsideOfMaze_ThrowsException()
        {
            var mazeToTest    = GetTestMaze();
            var mazeGridpoint = new MazeGridpoint(new CartesianCoordinate(1, 0), new DirectionsAvailable(), false, false, false);

            mazeToTest.ProceedToNewGridpoint(mazeGridpoint, DirectionEnum.Up);
        }
Esempio n. 5
0
        public void IsValidPositionInMaze_DirectionMovesOutOfMaze_ReturnsFalse()
        {
            var mazeToTest    = GetTestMaze();
            var mazeGridpoint = new MazeGridpoint(new CartesianCoordinate(1, 0), new DirectionsAvailable(), false, false, false);

            Assert.IsFalse(mazeToTest.IsValidPositionInMaze(mazeGridpoint, DirectionEnum.Up));
        }
Esempio n. 6
0
        public void CheckIfAtDeadEnd_GridpointHasMoreThanOneOpenPath_ReturnsFalse()
        {
            var mazeToTest    = GetTestMaze();
            var mazeGridpoint = new MazeGridpoint(new CartesianCoordinate(1, 0), new DirectionsAvailable(), false, false, false);

            Assert.IsFalse(mazeToTest.CheckIfAtDeadEnd(mazeGridpoint));
        }
Esempio n. 7
0
        public void IsValidPositionInMazeAndNotBacktracking_DirectionStaysInsideOfMazeAndIsNotBacktracking_ReturnsTrue()
        {
            var mazeToTest          = GetTestMaze();
            var firstMazeGridpoint  = new MazeGridpoint(new CartesianCoordinate(0, 0), new DirectionsAvailable(), true, false, false);
            var secondMazeGridpoint = new MazeGridpoint(new CartesianCoordinate(1, 0), new DirectionsAvailable(), false, false, false);

            Assert.IsTrue(mazeToTest.IsValidPositionInMazeAndNotBacktracking(firstMazeGridpoint, secondMazeGridpoint, DirectionEnum.Down));
        }
        public void ConvertMazeGridpointToPixelColor_GridpointIsWall_ColorIsBlack()
        {
            var coordinate    = new CartesianCoordinate(0, 0);
            var directions    = new DirectionsAvailable();
            var mazeGridpoint = new MazeGridpoint(coordinate, directions, false, false, true);

            var pixelColor = MazeGridpointConverter.ConvertMazeGridpointToPixelColor(mazeGridpoint);

            Assert.AreEqual(pixelColor.ToArgb(), Color.Black.ToArgb());
        }
Esempio n. 9
0
        public void ProceedToNewGridpoint_DirectionIsRight_ExpectedGridpointIsReturned()
        {
            var mazeToTest    = GetTestMaze();
            var mazeGridpoint = new MazeGridpoint(new CartesianCoordinate(1, 0), new DirectionsAvailable(), false, false, false);
            var newGridpoint  = mazeToTest.ProceedToNewGridpoint(mazeGridpoint, DirectionEnum.Down);

            var expectedGridpoint = new MazeGridpoint(new CartesianCoordinate(1, 1), new DirectionsAvailable(), false, true, false);

            Assert.AreEqual(newGridpoint.Position, expectedGridpoint.Position);
        }
Esempio n. 10
0
        public void CheckIfAtDeadEnd_GridpointHasOnlyOneOpenPath_ReturnsTrue()
        {
            var mazeToTest    = GetTestMaze();
            var mazeGridpoint = new MazeGridpoint(new CartesianCoordinate(1, 0), new DirectionsAvailable(), false, false, false);

            mazeGridpoint.DirectionsAvailable[DirectionEnum.Up]    = false;
            mazeGridpoint.DirectionsAvailable[DirectionEnum.Left]  = false;
            mazeGridpoint.DirectionsAvailable[DirectionEnum.Right] = false;

            Assert.IsTrue(mazeToTest.CheckIfAtDeadEnd(mazeGridpoint));
        }
        public void ConvertMazeGridpointToPixelColor_GridpointOHasBeenVisited_ColorIsGray()
        {
            var coordinate    = new CartesianCoordinate(0, 0);
            var directions    = new DirectionsAvailable();
            var mazeGridpoint = new MazeGridpoint(coordinate, directions, false, false, false);

            mazeGridpoint.HasBeenVisited   = true;
            mazeGridpoint.IsOnSolutionPath = false;
            var pixelColor = MazeGridpointConverter.ConvertMazeGridpointToPixelColor(mazeGridpoint);

            Assert.AreEqual(pixelColor.ToArgb(), Color.Gray.ToArgb());
        }
        public void PickDirectionToProceed_LastDirectionProceededWasDownAndCannotProceedInDirectionUpDownOrLeft_PicksDirectionRight()
        {
            var currentMazeGridpoint =
                new MazeGridpoint(new CartesianCoordinate(2, 2), new DirectionsAvailable(), false, false, false);

            var solutionPath = new List <MazeSolutionElement>
            {
                new MazeSolutionElement
                {
                    DirectionProceeded = DirectionEnum.Down,
                    MazeGridpoint      = new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false)
                },
                new MazeSolutionElement
                {
                    DirectionProceeded = DirectionEnum.Down,
                    MazeGridpoint      = new MazeGridpoint(new CartesianCoordinate(2, 1), new DirectionsAvailable(), true, false, false)
                }
            };

            var listOfMazeGridpoints = new List <MazeGridpoint>
            {
                new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false),
                new MazeGridpoint(new CartesianCoordinate(0, 2), new DirectionsAvailable(), false, false, true),

                new MazeGridpoint(new CartesianCoordinate(1, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 2), new DirectionsAvailable(), false, false, false),

                currentMazeGridpoint,

                new MazeGridpoint(new CartesianCoordinate(3, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 3), new DirectionsAvailable(), false, false, false),

                new MazeGridpoint(new CartesianCoordinate(4, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 4), new DirectionsAvailable(), false, true, false)
            };

            var mazeToTest      = new Maze(listOfMazeGridpoints.ToDictionary(m => m.Position, m => m));
            var directionPicker = new StraightLineDirectionPicker(mazeToTest);

            currentMazeGridpoint.DirectionsAvailable[DirectionEnum.Down] = false;
            currentMazeGridpoint.DirectionsAvailable[DirectionEnum.Left] = false;

            var directionToProceed = directionPicker.PickDirectionToProceed(solutionPath, currentMazeGridpoint);

            Assert.AreEqual(directionToProceed, DirectionEnum.Right);
        }
        public void PickDirectionToProceed_CannotProceedInAnydirection_PicksDirectionNone()
        {
            var currentMazeGridpoint =
                new MazeGridpoint(new CartesianCoordinate(2, 2), new DirectionsAvailable(), false, false, false);

            var solutionPath = new List <MazeSolutionElement>
            {
                new MazeSolutionElement
                {
                    MazeGridpoint = new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false)
                },
                new MazeSolutionElement
                {
                    MazeGridpoint = new MazeGridpoint(new CartesianCoordinate(2, 1), new DirectionsAvailable(), true, false, false)
                }
            };

            var listOfMazeGridpoints = new List <MazeGridpoint>
            {
                new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false),
                new MazeGridpoint(new CartesianCoordinate(0, 2), new DirectionsAvailable(), false, false, true),

                new MazeGridpoint(new CartesianCoordinate(1, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 2), new DirectionsAvailable(), false, false, false),

                currentMazeGridpoint,

                new MazeGridpoint(new CartesianCoordinate(3, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 3), new DirectionsAvailable(), false, false, false),

                new MazeGridpoint(new CartesianCoordinate(4, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 4), new DirectionsAvailable(), false, true, false)
            };

            var mazeToTest      = new Maze(listOfMazeGridpoints.ToDictionary(m => m.Position, m => m));
            var directionPicker = new WallHuggingDirectionPicker(mazeToTest);

            currentMazeGridpoint.DirectionsAvailable[DirectionEnum.Down]  = false;
            currentMazeGridpoint.DirectionsAvailable[DirectionEnum.Left]  = false;
            currentMazeGridpoint.DirectionsAvailable[DirectionEnum.Right] = false;

            var directionToProceed = directionPicker.PickDirectionToProceed(solutionPath, currentMazeGridpoint);

            Assert.AreEqual(directionToProceed, DirectionEnum.None);
        }
        public void ConvertMazeGridpointToPixelColor_GridpointIsStart_ColorIsRed()
        {
            var coordinate    = new CartesianCoordinate(0, 0);
            var directions    = new DirectionsAvailable();
            var mazeGridpoint = new MazeGridpoint(coordinate, directions, true, false, false);

            mazeGridpoint.HasBeenVisited = false;
            var pixelColor = MazeGridpointConverter.ConvertMazeGridpointToPixelColor(mazeGridpoint);

            Assert.AreEqual(pixelColor.ToArgb(), Color.Red.ToArgb());

            mazeGridpoint.HasBeenVisited = true;
            pixelColor = MazeGridpointConverter.ConvertMazeGridpointToPixelColor(mazeGridpoint);
            Assert.AreEqual(pixelColor.ToArgb(), Color.Red.ToArgb());
        }
        public void PickDirectionToProceed_NoCellsAreWallAdjacentAndLastDirectionProceededWasDown_PicksDirectionDown()
        {
            var currentMazeGridpoint =
                new MazeGridpoint(new CartesianCoordinate(2, 2), new DirectionsAvailable(), false, false, false);

            var solutionPath = new List <MazeSolutionElement>
            {
                new MazeSolutionElement
                {
                    DirectionProceeded = DirectionEnum.Down,
                    MazeGridpoint      = new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false)
                },
                new MazeSolutionElement
                {
                    DirectionProceeded = DirectionEnum.Down,
                    MazeGridpoint      = new MazeGridpoint(new CartesianCoordinate(2, 1), new DirectionsAvailable(), true, false, false)
                }
            };

            var listOfMazeGridpoints = new List <MazeGridpoint>
            {
                new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false),
                new MazeGridpoint(new CartesianCoordinate(0, 2), new DirectionsAvailable(), false, false, false),

                new MazeGridpoint(new CartesianCoordinate(1, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 2), new DirectionsAvailable(), false, false, false),

                currentMazeGridpoint,

                new MazeGridpoint(new CartesianCoordinate(3, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 3), new DirectionsAvailable(), false, false, false),

                new MazeGridpoint(new CartesianCoordinate(4, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 4), new DirectionsAvailable(), false, true, false)
            };

            var mazeToTest      = new Maze(listOfMazeGridpoints.ToDictionary(m => m.Position, m => m));
            var directionPicker = new WallHuggingDirectionPicker(mazeToTest);

            var directionToProceed = directionPicker.PickDirectionToProceed(solutionPath, currentMazeGridpoint);

            Assert.AreEqual(directionToProceed, DirectionEnum.Down);
        }
Esempio n. 16
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>
        /// Given a direction to proceed, this logic determines what the next maze gridpoint will be. In cases
        /// where we have reached a dead-end, this may mean backtracking to the last gridpoint where another
        /// choice was available.
        /// </summary>
        private MazeGridpoint DetermineNextMazeGridPoint(MazeGridpoint currentMazeGridpoint, DirectionEnum directionToProceed)
        {
            var nextMazeGridpoint = MazeToSolve.ProceedToNewGridpoint(currentMazeGridpoint, directionToProceed);

            if (MazeToSolve.CheckIfAtDeadEnd(nextMazeGridpoint) || nextMazeGridpoint.HasBeenVisited)
            {
                // We have arrived at a dead-end, so this cannot have been the right direction to proceed
                currentMazeGridpoint.DirectionsAvailable[directionToProceed] = false;

                if (currentMazeGridpoint.DirectionsAvailable.Count == 1)
                {
                    // Go back to the last gridpoint where there were more than two choices about the direction to proceed
                    var lastValidMazeSolutionElement = PathToSolveMaze.LastOrDefault(p => p.MazeGridpoint.DirectionsAvailable.Count > 2);
                    if (lastValidMazeSolutionElement == null)
                    {
                        throw new Exception("Maze Solver Error: Sorry, maze could not be solved. The maze image provided may be invalid.");
                    }

                    var directionProceededAtLastValidMazeGridPoint = lastValidMazeSolutionElement.DirectionProceeded;

                    // Since the path resulted in a dead-end, it cannot have been the reight direction to proceed
                    lastValidMazeSolutionElement.MazeGridpoint.DirectionsAvailable[directionProceededAtLastValidMazeGridPoint] = false;

                    // Truncate the path back to the last valid point to take a new direction
                    PathToSolveMaze = PathToSolveMaze.Where(p => p.StepNumber < lastValidMazeSolutionElement.StepNumber).ToList();

                    return(lastValidMazeSolutionElement.MazeGridpoint);
                }

                return(currentMazeGridpoint);
            }

            // The step numbers will be indexed starting with zero
            var stepNumber          = PathToSolveMaze.Count;
            var mazeSolutionElement = new MazeSolutionElement
            {
                StepNumber         = stepNumber,
                MazeGridpoint      = currentMazeGridpoint,
                DirectionProceeded = directionToProceed
            };

            PathToSolveMaze.Add(mazeSolutionElement);

            return(nextMazeGridpoint);
        }
        public void PickDirectionToProceed_CannotProceedInDirectionUpSinceItIsConsideredBacktracking_PicksDirectionDown()
        {
            var currentMazeGridpoint =
                new MazeGridpoint(new CartesianCoordinate(2, 2), new DirectionsAvailable(), false, false, false);

            var solutionPath = new List <MazeSolutionElement>
            {
                new MazeSolutionElement
                {
                    MazeGridpoint = new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false)
                },
                new MazeSolutionElement
                {
                    MazeGridpoint = new MazeGridpoint(new CartesianCoordinate(2, 1), new DirectionsAvailable(), true, false, false)
                }
            };

            var listOfMazeGridpoints = new List <MazeGridpoint>
            {
                new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false),
                new MazeGridpoint(new CartesianCoordinate(0, 2), new DirectionsAvailable(), false, false, true),

                new MazeGridpoint(new CartesianCoordinate(1, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 1), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 2), new DirectionsAvailable(), false, false, false),

                currentMazeGridpoint,

                new MazeGridpoint(new CartesianCoordinate(3, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(1, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 3), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(3, 3), new DirectionsAvailable(), false, false, false),

                new MazeGridpoint(new CartesianCoordinate(4, 2), new DirectionsAvailable(), false, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 4), new DirectionsAvailable(), false, true, false)
            };

            var mazeToTest      = new Maze(listOfMazeGridpoints.ToDictionary(m => m.Position, m => m));
            var directionPicker = new BaseDirectionPicker(mazeToTest);

            var directionToProceed = directionPicker.PickDirectionToProceed(solutionPath, currentMazeGridpoint);

            Assert.AreEqual(directionToProceed, DirectionEnum.Down);
        }
        public void PickDirectionToProceed_PassIncorrectTypeOfSolutionElements_ThrowsException()
        {
            var currentMazeGridpoint =
                new MazeGridpoint(new CartesianCoordinate(2, 2), new DirectionsAvailable(), false, false, false);

            var listOfMazeGridpoints = new List <MazeGridpoint>
            {
                currentMazeGridpoint,
                new MazeGridpoint(new CartesianCoordinate(2, 0), new DirectionsAvailable(), true, false, false),
                new MazeGridpoint(new CartesianCoordinate(2, 4), new DirectionsAvailable(), false, true, false)
            };

            var mazeToTest      = new Maze(listOfMazeGridpoints.ToDictionary(m => m.Position, m => m));
            var directionPicker = new StraightLineDirectionPicker(mazeToTest);
            var mazeSolution    = new MazeSolutionElementTree();

            directionPicker.PickDirectionToProceed(mazeSolution, currentMazeGridpoint);
        }
Esempio n. 20
0
        /// <summary>
        /// Picks a direction in this order of preference: Up, Down, Left, Right.
        /// </summary>
        public virtual DirectionEnum PickDirectionToProceed(object mazeSolutionElements, MazeGridpoint mazeGridpoint)
        {
            var pathToSolveMaze = mazeSolutionElements as List <MazeSolutionElement>;

            if (pathToSolveMaze == null)
            {
                throw new Exception("Maze solution elements used are not supported by BaseDirectionPicker");
            }

            // There cannot be any back-tracking if there is nothing in the path to solve the maze
            if (pathToSolveMaze.Any())
            {
                var lastMazeGridpoint = pathToSolveMaze.Last().MazeGridpoint;

                // Take the first path that does not lead back to the last position in the maze on the path traced so far
                // AND, is a valid position inside the boundaries of the maze
                var directionToProceed = mazeGridpoint.DirectionsAvailable.OpenPaths
                                         .FirstOrDefault(direction => MazeToSolve.IsValidPositionInMazeAndNotBacktracking(lastMazeGridpoint, mazeGridpoint, direction));

                return(directionToProceed);
            }

            // Take the first path that is valid
            return(mazeGridpoint.DirectionsAvailable.OpenPaths
                   .FirstOrDefault(direction =>
                                   MazeToSolve.IsValidPositionInMaze(mazeGridpoint, direction)));
        }
        /// <summary>
        /// Picks a direction that is consitent with the last direction proceeded, if possible.
        /// </summary>
        public override DirectionEnum PickDirectionToProceed(object mazeSolutionElements, MazeGridpoint mazeGridpoint)
        {
            var pathToSolveMaze = mazeSolutionElements as List <MazeSolutionElement>;

            if (pathToSolveMaze == null)
            {
                throw new Exception("Maze solution elements used are not supported by BaseDirectionPicker");
            }

            if (pathToSolveMaze.Any())
            {
                var lastMazeSolutionElement = pathToSolveMaze.Last();
                var lastMazeGridpoint       = lastMazeSolutionElement.MazeGridpoint;
                var lastDirectionProceeded  = lastMazeSolutionElement.DirectionProceeded;

                // Find all paths that do not lead back to the last position in the maze on the path traced so far
                // AND, are valid positions inside the boundaries of the maze
                var potentialDirectionsToProceed = mazeGridpoint.DirectionsAvailable.OpenPaths
                                                   .Where(direction =>
                                                          MazeToSolve.IsValidPositionInMazeAndNotBacktracking(lastMazeGridpoint, mazeGridpoint, direction)).ToList();

                // If it's possible to keep going in a straight line, continue to do so
                if (potentialDirectionsToProceed.Contains(lastDirectionProceeded))
                {
                    return(lastDirectionProceeded);
                }

                return(potentialDirectionsToProceed.FirstOrDefault());
            }

            // Take the first path that is valid
            return(mazeGridpoint.DirectionsAvailable.OpenPaths
                   .FirstOrDefault(direction =>
                                   MazeToSolve.IsValidPositionInMaze(mazeGridpoint, direction)));
        }