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); }
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)); }
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)); }
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); }
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)); }
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)); }
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()); }
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); }
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); }
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); }
/// <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))); }