Пример #1
0
        public static HashSet <Point> generateMaze(int width, int height)
        {
            var V          = new HashSet <Point>();
            var discovered = RecursiveBacktrackerAlgorithm.ReturnDict(width, height);
            var maze       = new HashSet <Point>();

            var weights = returnWeights(discovered.Keys.ToList());

            var startV   = new Point(5, 3);
            var currentV = startV;

            discovered[startV] = true;

            var r = new Random();

            var mazeEntry = new Point(5, 2);

            maze.Add(mazeEntry);
            maze.Add(currentV);

            while (true)
            {
                var availableVertices = Program.returnUnvisitedNeighbours(discovered, currentV);

                foreach (var vertex in availableVertices.Where(vertex => !V.Contains(vertex)))
                {
                    V.Add(vertex);
                }

                if (V.Count == 0)
                {
                    break;
                }

                var lowestWeightVertex = ExtractMinV(V, weights);

                var visitedNeighbours = returnVisitedNeighbours(discovered, lowestWeightVertex);

                var newVertex = visitedNeighbours[r.Next(visitedNeighbours.Count)];

                var wallV = RecursiveBacktrackerAlgorithm.pointMidPoint(newVertex, lowestWeightVertex);

                maze.Add(wallV);
                maze.Add(lowestWeightVertex);

                currentV = lowestWeightVertex;

                V.Remove(currentV);

                discovered[currentV] = true;
            }

            var mazeExit = RecursiveBacktrackerAlgorithm.returnExit(width, height);

            maze.Add(mazeExit);

            return(maze);
        }
Пример #2
0
        public static HashSet <Point> generateMaze(int width, int height)
        {
            var startV   = new Point(5, 3);
            var currentV = startV;
            var prev     = startV;

            var maze = new HashSet <Point>
            {
                new Point(5, 2),
                currentV
            };

            var r = new Random();

            var visited = RecursiveBacktrackerAlgorithm.ReturnDict(width, height);

            Program.setBothColours(ConsoleColor.White);

            visited[currentV] = true;

            while (unvisitedVertices(visited))
            {
                var surroundingVertices = returnNeighbours(visited, currentV);

                var temporaryVertex = surroundingVertices[r.Next(surroundingVertices.Count)];

                if (!visited[temporaryVertex])
                {
                    var wallV = RecursiveBacktrackerAlgorithm.pointMidPoint(currentV, temporaryVertex);

                    visited[temporaryVertex] = true;

                    maze.Add(wallV);
                    maze.Add(temporaryVertex);
                }

                currentV = temporaryVertex;
            }


            var mazeExit = RecursiveBacktrackerAlgorithm.returnExit(width, height);

            maze.Add(mazeExit);


            return(maze);
        }
        /// <summary>
        /// generates a hamiltonian graph which contains every vertex in the maze
        /// pseudocode:
        ///     while there are unvisited positions:
        ///         if there are unvisited adjacent vertices
        ///             perform a non overlapping random walk
        ///         else
        ///             pick a random adjacent vertex that isn't connected to the trapped point
        ///             connect to the random vertex, named the target vertex
        ///             indentify the two adjacent vertices that are next to the target vertex
        ///             run depth first search from one of the two adjacent vertices until the stack is empty or until the trapped point is reached
        ///             if the trapped point is reached then remove the vertex that connected it
        ///             make the current vertex the vertex adjacent to the vertex that was just removed that isn't the target vertex
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <returns>
        /// Returns a hashset which contains points that are the maze
        /// </returns>
        //todo add scoring to the random vertex walk in order to improve efficiency, need to fix start/endpoint thing
        public static HashSet <Point> generateMaze(int width, int height)
        {
            var startV   = new Point(5, 3);
            var endV     = new Point(9, 3);
            var currentV = startV;

            var visited = RecursiveBacktrackerAlgorithm.ReturnDict(width, height);

            var maze = new HashSet <Point>();

            visited[startV] = true;
            maze.Add(startV);

            var r = new Random();

            Program.setBothColours(ConsoleColor.White);
            Program.printPoint(currentV);

            while (true)
            {
                var availableVertices = Program.returnUnvisitedNeighbours(visited, currentV);

                if (availableVertices.Count > 0)
                {
                    Program.setBothColours(ConsoleColor.White);

                    var temporaryV = availableVertices[r.Next(availableVertices.Count)];

                    visited[temporaryV] = true;

                    var wallV = RecursiveBacktrackerAlgorithm.pointMidPoint(currentV, temporaryV);

                    maze.Add(wallV);
                    maze.Add(temporaryV);

                    Program.printPoint(wallV);
                    Program.printPoint(temporaryV);

                    currentV = temporaryV;
                }
                else
                {
                    Program.setBothColours(ConsoleColor.White);
                    var endPoint = currentV;

                    Program.printPoint(endPoint);
                    //end point is selected as the current as it has no neighbours

                    //all surrounding points, doesnt take into account the maze at all
                    var neighbours = returnAdjacentVertices(endPoint);

                    //the valid available neighbouring vertices
                    var validChoices = neighbours.Where(potentialVertex =>
                                                        !isConnected(maze, endPoint, potentialVertex)
                                                        & visited.ContainsKey(potentialVertex)).ToList();

                    //chooses a random vertex from the available surrounding vertices
                    var targetVertex = validChoices[r.Next(validChoices.Count)];


                    //draws the edge and the target vertices in green

                    var wall = RecursiveBacktrackerAlgorithm.pointMidPoint(targetVertex, endPoint);
                    Program.printPoint(wall);

                    Program.printPoint(targetVertex);

                    (Point, Point)verticesToAdd = (wall, targetVertex);


                    //gets new surrounding vertices with the target vertex as the centre
                    neighbours = returnVertices(targetVertex);

                    //adjacent nodes from the target vertex; the edges that connect the target vertex to the adjacent vertices
                    var connectedVertices = neighbours.Where(potentialVertex =>
                                                             maze.Contains(potentialVertex)).ToList();

                    //run depth first search to see if there is a loop in the maze coming from one of the adjacent vertices
                    //sets the root equal to come of the adjacent vertices
                    var root = connectedVertices.First();


                    //create a temporary maze that doesnt include the target node so that the search is forced down a single path
                    var tempMaze = maze;

                    tempMaze.Remove(targetVertex);

                    //create a visited dictionary
                    var d = maze.ToDictionary(v => v, v => false);

                    //return the depth first search result
                    var isconnected = connectedVertex(tempMaze, root, endPoint, d);

                    var pointToBeRemoved = root;

                    //deciding which adjacent vertex to remove
                    if (!isconnected)
                    {
                        pointToBeRemoved = connectedVertices.Last();
                    }

                    //removing the vertex
                    Program.setBothColours(ConsoleColor.Black);
                    Program.printPoint(pointToBeRemoved);
                    maze.Remove(pointToBeRemoved);

                    //get the new point to begin the random walk from
                    neighbours = Program.returnAdjacentVertices(maze, pointToBeRemoved);

                    foreach (var v in neighbours.Where(v => !v.Equals(targetVertex)))
                    {
                        currentV = v;
                        break;
                    }

                    visited[currentV] = true;

                    maze.Add(verticesToAdd.Item1);
                    maze.Add(verticesToAdd.Item2);
                }

                if (currentV.Equals(endV))
                {
                    if (!unvisitedVertices(visited))
                    {
                        break;
                    }
                }
            }

            var startAndEnd = returnStartAndGoal(maze);

            maze = removeDuplicate(maze);

            maze.Reverse();
            maze.Add(startAndEnd.Item1);
            maze.Reverse();
            maze.Add(startAndEnd.Item2);

            Program.setBothColours(ConsoleColor.Green);
            Program.printPoint(maze.First());
            Program.setBothColours(ConsoleColor.Red);
            Program.printPoint(maze.Last());

            Console.ReadKey();

            return(maze);
        }
 private static bool isConnected(HashSet <Point> maze, Point currentPoint, Point newPoint) =>
 maze.Contains(RecursiveBacktrackerAlgorithm.pointMidPoint(currentPoint, newPoint));
        public static HashSet <Point> generateMaze(int width, int height)
        {
            var startV   = new Point(5, 3);
            var currentV = startV;

            var visited = RecursiveBacktrackerAlgorithm.ReturnDict(width, height);

            var maze = new HashSet <Point>();

            var mazeEntry = new Point(5, 2);

            maze.Add(mazeEntry);

            visited[startV] = true;
            maze.Add(startV);

            var r = new Random();

            while (unvisitedVertices(visited))
            {
                var availableVertices = Program.returnUnvisitedNeighbours(visited, currentV);

                if (availableVertices.Count > 0)
                {
                    var temporaryV = availableVertices[r.Next(availableVertices.Count)];

                    visited[temporaryV] = true;

                    var wallV = RecursiveBacktrackerAlgorithm.pointMidPoint(currentV, temporaryV);

                    maze.Add(wallV);
                    maze.Add(temporaryV);

                    currentV = temporaryV;
                }
                else
                {
                    foreach (Point v in visited.Keys)
                    {
                        var visitedNeighbours = PrimsAlgorithm.returnVisitedNeighbours(visited, v);
                        if (visitedNeighbours.Count == 0 || visited[v])
                        {
                            continue;
                        }
                        else
                        {
                            var newVertex = visitedNeighbours[r.Next(visitedNeighbours.Count)];

                            var wallV = RecursiveBacktrackerAlgorithm.pointMidPoint(newVertex, v);

                            maze.Add(wallV);
                            maze.Add(v);

                            currentV = v;

                            break;
                        }
                    }
                    visited[currentV] = true;
                }
            }


            var mazeExit = RecursiveBacktrackerAlgorithm.returnExit(width, height);

            maze.Add(mazeExit);

            return(maze);
        }
        public static HashSet <Point> generateMaze(int width, int height)
        {
            var r = new Random();

            var visited = RecursiveBacktrackerAlgorithm.ReturnDict(width, height);

            var cameFrom = resetCameFrom(visited);

            //Choose any vertex at random and add it to the UST.
            //Select any vertex that is not already in the UST and perform a random walk until you encounter a vertex that is in the UST.
            //Add the vertices and edges touched in the random walk to the UST.
            //Repeat 2 and 3 until all vertices have been added to the UST.

            var UST = new HashSet <Point>();

            var currentV = visited.Keys.ToList()[r.Next(visited.Keys.Count)];
            var prev     = currentV;

            visited[currentV] = true;

            var maze = new HashSet <Point>
            {
                new Point(5, 2),
                currentV
            };

            UST.Add(currentV);


            currentV = getUnvisitedVertex(visited);

            var firstCell = currentV;


            while (unvisitedVertices(visited))
            {
                var surroundingVertices = returnNeighbours(visited, currentV);

                var temporaryVertex = surroundingVertices[r.Next(surroundingVertices.Count)];

                cameFrom[prev] = temporaryVertex;


                if (UST.Contains(temporaryVertex))
                {
                    temporaryVertex = firstCell;

                    var verticesToBeAdded = new List <Point>
                    {
                        temporaryVertex
                    };


                    do
                    {
                        if (!cameFrom.ContainsKey(temporaryVertex))
                        {
                            break;
                        }

                        temporaryVertex = cameFrom[temporaryVertex];
                        verticesToBeAdded.Add(temporaryVertex);
                    } while (!UST.Contains(temporaryVertex));


                    for (int i = 0; i < verticesToBeAdded.Count - 1; i++)
                    {
                        var v1   = verticesToBeAdded[i];
                        var v2   = verticesToBeAdded[i + 1];
                        var wall = RecursiveBacktrackerAlgorithm.pointMidPoint(v1, v2);

                        visited[v1] = true;

                        maze.Add(wall);
                        maze.Add(v1);

                        UST.Add(v1);
                    }

                    cameFrom = resetCameFrom(visited);

                    if (!unvisitedVertices(visited))
                    {
                        break;
                    }

                    currentV = getUnvisitedVertex(visited);

                    prev = currentV;

                    firstCell = currentV;
                }
                else
                {
                    currentV = temporaryVertex;

                    cameFrom[prev] = currentV;

                    prev = currentV;
                }
            }

            var mazeExit = RecursiveBacktrackerAlgorithm.returnExit(width, height);

            maze.Add(mazeExit);

            return(maze);
        }