private IEnumerable <CarvedCellResult> FillInPassage(IMazeCarver mazeCarver) { var list = new List <CarvedCellResult>(); var junctionOrStartOrEndReached = false; do { var directions = mazeCarver.GetsDirectionsFromPoint().ToList(); if (directions.Count() == 1) { var direction = directions.First(); mazeCarver.FillInDirection(direction); list.Add(new CarvedCellResult { Direction = direction, Point = mazeCarver.CurrentPoint }); mazeCarver.JumpInDirection(direction); if (_pointsAndDirectionsRetriever.PointIsStartOrEnd(mazeCarver.CurrentPoint, mazeCarver.StartPoint, mazeCarver.EndPoint)) { junctionOrStartOrEndReached = true; } } else { junctionOrStartOrEndReached = true; } } while (!junctionOrStartOrEndReached); return(list); }
private IEnumerable <CarvedCellResult> FillInPassage(IMazeCarver mazeCarver) { var directions = mazeCarver.GetsDirectionsFromPoint().ToList(); if (directions.Count() == 1) { var direction = directions.First(); mazeCarver.FillInDirection(direction); yield return(new CarvedCellResult { Direction = direction, Point = mazeCarver.CurrentPoint }); mazeCarver.JumpInDirection(direction); if (!_pointsAndDirectionsRetriever.PointIsStartOrEnd(mazeCarver.CurrentPoint, mazeCarver.StartPoint, mazeCarver.EndPoint)) { foreach (var d in FillInPassage(mazeCarver)) { yield return(d); } } } }
private IEnumerable <GraphEdge> GetGraphEdges(IMazeCarver carver, PointAndDirections junction) { foreach (var direction in junction.Directions) { var result = new GraphEdge { DirectionsToPoint = new List <Direction>() { direction } }; carver.JumpToPoint(junction.Point); carver.JumpInDirection(direction); Direction inputDirection = direction; bool endFound = false; do { var directions = carver.GetsDirectionsFromPoint().ToList(); if (IsStartOrEndPointOrJunction(carver, directions)) { result.Point = carver.CurrentPoint; endFound = true; } else { var oppositeDirection = _directionsFlagParser.OppositeDirection(inputDirection); directions = directions.Where(x => x != oppositeDirection).ToList(); inputDirection = directions.Single(); result.DirectionsToPoint.Add(inputDirection); carver.JumpInDirection(inputDirection); } } while (!endFound); yield return(result); } }
private void RandomCarveWalls(IMazeCarver carver, int numberOfWalls) { while (numberOfWalls > 0) { numberOfWalls = CheckPoint(_randomPointGenerator.RandomPoint(carver.Size), carver, numberOfWalls); } }
public AlgorithmRunResults GenerateMaze(IMazeCarver maze, MazeGenerationSettings settings) { var pointsAndDirections = new List <DirectionAndPoint>(); _mazeHelper.DoForEachPoint(maze.Size, p => { maze.JumpToPoint(p); var directions = _directions.Where(maze.CanCarveInDirection).ToList(); _arrayHelper.Shuffle(directions); if (directions.Any()) { var first = directions.First(); pointsAndDirections.Add(new DirectionAndPoint { Direction = first, MazePoint = maze.CurrentPoint }); maze.CarveInDirection(first); } }); return(new AlgorithmRunResults { Carver = maze, DirectionsCarvedIn = pointsAndDirections }); }
public AlgorithmRunResults GenerateMaze(IMazeCarver maze, MazeGenerationSettings settings) { var randomPoint = _randomPointGenerator.RandomPoint(maze.Size); maze.JumpToPoint(randomPoint); return(RecursiveBackTracker(maze)); }
public AlgorithmRunResults RecursiveBackTracker(IMazeCarver carver) { var pointsAndDirections = new List <DirectionAndPoint>(); var directions = carver.CarvableDirections().ToList(); _arrayHelper.Shuffle(directions); var currentPoint = carver.CurrentPoint; foreach (var direction in directions) { carver.JumpInDirection(direction); var carvedDirections = carver.AlreadyCarvedDirections(); if (!carvedDirections.Any()) { pointsAndDirections.Add(new DirectionAndPoint { Direction = direction, MazePoint = currentPoint }); var oppositeDirection = _directionsFlagParser.OppositeDirection(direction); carver.CarveInDirection(oppositeDirection); RecursiveBackTracker(carver); } carver.JumpToPoint(currentPoint); } return(new AlgorithmRunResults { Carver = carver, DirectionsCarvedIn = pointsAndDirections }); }
public Graph GetGraphFromMaze(IMazeCarver carver) { carver.SetState(ModelMode.DeadEndFilled); var dictionary = new Dictionary <MazePoint, GraphNode>(); var junctions = _directionsRetriever.GetJunctions(carver); foreach (var junction in junctions) { var graphNode = new GraphNode { Edges = GetGraphEdges(carver, junction).ToList(), ShortestPath = int.MaxValue, ShortestPathDirections = new List <Direction>() }; dictionary.Add(junction.Point, graphNode); } if (!dictionary.ContainsKey(carver.StartPoint)) { carver.JumpToPoint(carver.StartPoint); var junction = new PointAndDirections { Point = carver.CurrentPoint, Directions = carver.GetsDirectionsFromPoint().ToList(), }; var graphNode = new GraphNode { Edges = GetGraphEdges(carver, junction).ToList(), ShortestPath = int.MaxValue, ShortestPathDirections = new List <Direction>() }; dictionary.Add(carver.StartPoint, graphNode); } if (!dictionary.ContainsKey(carver.EndPoint)) { carver.JumpToPoint(carver.EndPoint); var junction = new PointAndDirections { Point = carver.CurrentPoint, Directions = carver.GetsDirectionsFromPoint().ToList() }; var graphNode = new GraphNode { Edges = GetGraphEdges(carver, junction).ToList(), ShortestPath = int.MaxValue, ShortestPathDirections = new List <Direction>() }; dictionary.Add(carver.EndPoint, graphNode); } carver.SetState(ModelMode.Standard); return(new Graph { Nodes = dictionary, }); }
public AlgorithmRunResults GenerateMaze(IMazeCarver maze, MazeGenerationSettings settings) { var growingTreeSettings = settings as GrowingTreeSettings; if (growingTreeSettings == null) { throw new ArgumentException("The correct settings are not present"); } return(GenerateMaze(maze, growingTreeSettings.Strategies)); }
private IEnumerable <PointAndDirections> GetPointsWithDirections(IMazeCarver carver) { return(_mazeHelper.GetForEachPoint(carver.Size, point => { carver.JumpToPoint(point); return new PointAndDirections { Point = point, Directions = carver.GetsDirectionsFromPoint().ToList() }; })); }
public ShortestPathResult GetGraph(IMazeCarver carver) { var graph = _graphBuilder.GetGraphFromMaze(carver); graph.Nodes[carver.StartPoint].ShortestPath = 0; ProcessGraph(graph); var node = graph.Nodes[carver.EndPoint]; return(new ShortestPathResult { Graph = graph, ShortestPath = node.ShortestPath, ShortestPathDirections = node.ShortestPathDirections }); }
private int CheckPoint(MazePoint point, IMazeCarver carver, int numberOfWalls, Direction preferredDirection = Direction.None) { carver.JumpToPoint(point); var directions = carver.CarvableDirections().ToList(); _arrayHelper.Shuffle(directions); if (directions.Any()) { var selectedDirection = directions.Contains(preferredDirection) ? preferredDirection : directions.First(); carver.CarveInDirection(selectedDirection); numberOfWalls--; } return(numberOfWalls); }
public AlgorithmRunResults GenerateMaze(IMazeCarver maze, MazeGenerationSettings settings) { var pointAndDirection = new List <DirectionAndPoint>(); var randomPoint = _randomPointGenerator.RandomPoint(maze.Size); maze.JumpToPoint(randomPoint); var activeCells = new LinkedList <MazePoint>(); activeCells.AddLast(randomPoint); while (activeCells.Any()) { var currentPoint = activeCells.Last.Value; maze.JumpToPoint(currentPoint); var carvableDirections = maze.CarvableDirections().ToList(); _arrayHelper.Shuffle(carvableDirections); var carved = false; foreach (var direction in carvableDirections) { maze.JumpInDirection(direction); var carvedDirections = maze.AlreadyCarvedDirections(); if (!carvedDirections.Any()) { pointAndDirection.Add(new DirectionAndPoint { Direction = direction, MazePoint = currentPoint }); var oppositeDirection = _directionsFlagParser.OppositeDirection(direction); maze.CarveInDirection(oppositeDirection); activeCells.AddLast(maze.CurrentPoint); carved = true; break; } maze.JumpToPoint(currentPoint); } if (!carved) { activeCells.RemoveLast(); } } return(new AlgorithmRunResults { Carver = maze, DirectionsCarvedIn = pointAndDirection }); }
private AlgorithmRunResults GenerateMaze(IMazeCarver maze, List <GrowingTreeStrategy> strategies) { var pointsAndDirections = new List <DirectionAndPoint>(); var randomPoint = _randomPointGenerator.RandomPoint(maze.Size); var activeCells = new List <MazePoint> { randomPoint }; while (activeCells.Any()) { var currentPoint = GetNextPoint(activeCells, strategies); maze.JumpToPoint(currentPoint); var carvableDirections = maze.CarvableDirections().ToList(); _arrayHelper.Shuffle(carvableDirections); var carved = false; foreach (var direction in carvableDirections) { maze.JumpInDirection(direction); var carvedDirections = maze.AlreadyCarvedDirections(); if (!carvedDirections.Any()) { pointsAndDirections.Add(new DirectionAndPoint { Direction = direction, MazePoint = currentPoint }); var oppositeDirection = _directionsFlagParser.OppositeDirection(direction); maze.CarveInDirection(oppositeDirection); activeCells.Add(maze.CurrentPoint); carved = true; break; } maze.JumpToPoint(currentPoint); } if (!carved) { activeCells.Remove(currentPoint); } } return(new AlgorithmRunResults { Carver = maze, DirectionsCarvedIn = pointsAndDirections }); }
public void CarveRandomWalls(IMazeCarver carver, WallCarverOption option, int numberOfWalls) { switch (option) { case WallCarverOption.None: break; case WallCarverOption.Random: RandomCarveWalls(carver, numberOfWalls); break; case WallCarverOption.DeadEnd: DeadEndCarver(carver, numberOfWalls, false); break; case WallCarverOption.DeadEndWithPreferredDirection: DeadEndCarver(carver, numberOfWalls, true); break; default: throw new ArgumentOutOfRangeException(); } }
public DeadEndFillerResult Fill(IMazeCarver mazeCarver) { mazeCarver.DoDeadEndWrapping(model => { var deadEndModel = _deadEndModelWrapperFactory.MakeModel(model); return(deadEndModel); }); mazeCarver.SetState(ModelMode.DeadEndFilled); var deadEndsRemaining = true; var carvedDirections = new List <CarvedCellResult>(); while (deadEndsRemaining) { var pointsAndDirections = _pointsAndDirectionsRetriever .GetDeadEnds(mazeCarver) .Where(x => !_pointsAndDirectionsRetriever.PointIsStartOrEnd(x.Point, mazeCarver.StartPoint, mazeCarver.EndPoint)).ToList(); if (!pointsAndDirections.Any()) { deadEndsRemaining = false; } else { foreach (var pointAndDirection in pointsAndDirections) { mazeCarver.JumpToPoint(pointAndDirection.Point); carvedDirections.AddRange(FillInPassage(mazeCarver)); } } } mazeCarver.SetState(ModelMode.Standard); return(new DeadEndFillerResult { CellsFilledIn = carvedDirections, TotalCellsFilledIn = carvedDirections.Count }); }
private void DeadEndCarver(IMazeCarver carver, int numberOfWalls, bool hasPreferredDirection) { var pointsAndDirections = _pointsAndDirectionsRetriever.GetDeadEnds(carver).ToList(); _arrayHelper.Shuffle(pointsAndDirections); foreach (var pointAndDirections in pointsAndDirections) { if (numberOfWalls > 0) { Direction preferredDirection = Direction.None; if (hasPreferredDirection) { preferredDirection = _directionsFlagParser .OppositeDirection(pointAndDirections.Directions.First()); } numberOfWalls = CheckPoint(pointAndDirections.Point, carver, numberOfWalls, preferredDirection); } else { break; } } RandomCarveWalls(carver, numberOfWalls); }
private bool IsStartOrEndPointOrJunction(IMazeCarver carver, List <Direction> directions) { return(_directionsRetriever.PointIsStartOrEnd(carver.CurrentPoint, carver.StartPoint, carver.EndPoint) || _directionsRetriever.IsJunction(directions)); }
public IEnumerable <PointAndDirections> GetJunctions(IMazeCarver mazeCarver) { return(GetPointsWithDirections(mazeCarver).Where(x => IsJunction(x.Directions))); }
public IEnumerable <PointAndDirections> GetCorridoors(IMazeCarver mazeCarver) { return(GetPointsWithDirections(mazeCarver).Where(x => IsCorridoor(x.Directions))); }
public MazeGenerationResults GenerateMaze(MazeGenerationSettings settings) { IMazeCarver carver = null; var modelBuildTime = _timeRecorder.GetRunningTime(() => { var model = _mazeModelFactory.BuildMaze(settings); carver = _mazeFactory.GetMazeCarver(model); }); AlgorithmRunResults results = null; int extraWallsAdded = 0; var generationTime = _timeRecorder.GetRunningTime(() => { switch (settings.Algorithm) { case Algorithm.None: throw new ArgumentException("None not supported"); case Algorithm.GrowingTreeAlgorithm: results = _growingTreeAlgorithm.GenerateMaze(carver, settings); break; case Algorithm.RecursiveBacktrackerAlgorithm: results = _recursiveBacktrackerAlgorithm.GenerateMaze(carver, settings); break; case Algorithm.BinaryTreeAlgorithm: results = _binaryTreeAlgorithm.GenerateMaze(carver, settings); break; default: throw new ArgumentException("Unsupported algorithm type"); } carver = results.Carver; extraWallsAdded = _extraWall.Calulate(carver.Size); _randomCarver.CarveRandomWalls(carver, settings.ExtraWalls, extraWallsAdded); }); DeadEndFillerResult deadEndFillerResults = null; var deadEndFillerTime = _timeRecorder.GetRunningTime(() => { deadEndFillerResults = _deadEndFiller.Fill(carver); }); AgentResults result = null; var agentGenerationTime = _timeRecorder.GetRunningTime(() => { if (settings.AgentType != AgentType.None) { result = _agentFactory.MakeAgent(settings.AgentType).RunAgent(carver); } }); HeuristicsResults heuristicsResults = null; var heuristicsTime = _timeRecorder.GetRunningTime(() => { heuristicsResults = _heuristicsGenerator.GetResults(results); }); var times = new [] { modelBuildTime, generationTime, deadEndFillerTime, agentGenerationTime, heuristicsTime }; var totalTime = times.Aggregate(new TimeSpan(), (seed, value) => seed.Add(value)); return(new MazeGenerationResults { MazeJumper = carver.CarvingFinished(), HeuristicsResults = heuristicsResults, DirectionsCarvedIn = results.DirectionsCarvedIn, DeadEndFillerResults = deadEndFillerResults, ModelTime = modelBuildTime, AgentResults = result, GenerationTime = generationTime, DeadEndFillerTime = deadEndFillerTime, AgentGenerationTime = agentGenerationTime, HeuristicsTime = heuristicsTime, TotalTime = totalTime }); }