コード例 #1
0
        public static List <Vec2i> Cell_GeometricNeighbors_List(
            this PM_Maze maze,
            Vec2i pos
            )
        {
            List <Vec2i> geometricNeighbors = new List <Vec2i>();

            if (maze.Q_Is_Cell_InBounds(pos.To_Up()))
            {
                geometricNeighbors.Add(pos.To_Up());
            }
            if (maze.Q_Is_Cell_InBounds(pos.To_Down()))
            {
                geometricNeighbors.Add(pos.To_Down());
            }
            if (maze.Q_Is_Cell_InBounds(pos.To_Left()))
            {
                geometricNeighbors.Add(pos.To_Left());
            }
            if (maze.Q_Is_Cell_InBounds(pos.To_Right()))
            {
                geometricNeighbors.Add(pos.To_Right());
            }

            return(geometricNeighbors);
        }
コード例 #2
0
        public static List <Vec2i> Cells_Connected_To_Cell__List(
            this PM_Maze maze,
            Vec2i cell
            )
        {
            List <Vec2i> neighbors = new List <Vec2i>();

            Directions_Ortho_2D directions = maze.Q_Cell_Directions(cell);

            if (directions.HasFlag(Directions_Ortho_2D.U))
            {
                neighbors.Add(cell.To_Up());
            }
            if (directions.HasFlag(Directions_Ortho_2D.D))
            {
                neighbors.Add(cell.To_Down());
            }
            if (directions.HasFlag(Directions_Ortho_2D.L))
            {
                neighbors.Add(cell.To_Left());
            }
            if (directions.HasFlag(Directions_Ortho_2D.R))
            {
                neighbors.Add(cell.To_Right());
            }

            return(neighbors);
        }
 public static int Cell__Centrality(
     this PM_Maze maze,
     Vec2i cellPosition
     )
 {
     return(maze.Cell__Centrality(cellPosition.x, cellPosition.y));
 }
コード例 #4
0
 public static List <UEdge2i> Cell_ActiveEdges_List(
     this PM_Maze maze,
     int x,
     int y)
 {
     return(maze.Cell_ActiveEdges_List(new Vec2i(x, y)));
 }
コード例 #5
0
        public override double Evaluate(PM_Maze maze)
        {
            double verticalSymmetry   = maze.Symmetry_Over_X_Axis();
            double horizontalSymmetry = maze.Symmetry_Over_Y_Axis();

            return((verticalSymmetry + horizontalSymmetry) / 2.0);
        }
コード例 #6
0
        public override PM_Maze Generate_Maze(
            Random randomness_provider,
            int width,
            int height
            )
        {
            // initialize maze
            PM_Maze maze = new PM_Maze(width, height);

            Vec2i          current_position = maze.RandomCell(randomness_provider);
            List <UEdge2i> expansion_edges  = maze.Cell_ExpansionEdges_List(current_position);

            expansion_edges.Shuffle(randomness_provider);

            while (expansion_edges.Count > 0)
            {
                UEdge2i selected_edge = expansion_edges.Pop_Last_Item(); // select & remove (draw) the last edge
                current_position = selected_edge.exit;
                if (maze.Q_Is_Cell_Unconnected(current_position))
                {
                    maze.OP_AddEdge(selected_edge);
                    List <UEdge2i> newEdges = maze.Cell_ExpansionEdges_List(current_position);
                    newEdges.Shuffle(randomness_provider);
                    expansion_edges.AddRange(newEdges);
                }
            }
            return(maze);
        }
コード例 #7
0
        public static double Cells_Similarity(this PM_Maze maze, Vec2i cell1, Vec2i cell2)
        {
            int sum = 0;
            Directions_Ortho_2D dir1 = maze.Q_Cell_Directions(cell1);
            Directions_Ortho_2D dir2 = maze.Q_Cell_Directions(cell2);

            if (
                (dir1 & dir2).HasFlag(Directions_Ortho_2D.U)
                )
            {
                sum++;
            }
            if (
                (dir1 & dir2).HasFlag(Directions_Ortho_2D.D)
                )
            {
                sum++;
            }
            if (
                (dir1 & dir2).HasFlag(Directions_Ortho_2D.L)
                )
            {
                sum++;
            }
            if (
                (dir1 & dir2).HasFlag(Directions_Ortho_2D.R)
                )
            {
                sum++;
            }
            return((double)sum / 4.0);
        }
コード例 #8
0
        public static int Num_Cells_Corners(this PM_Maze maze)
        {
            int width  = maze.Q_Width();
            int height = maze.Q_Height();

            int numCorners = 0;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    if (
                        maze.cells[x, y] == (Directions_Ortho_2D.R | Directions_Ortho_2D.U)
                        ||
                        maze.cells[x, y] == (Directions_Ortho_2D.U | Directions_Ortho_2D.L)
                        ||
                        maze.cells[x, y] == (Directions_Ortho_2D.L | Directions_Ortho_2D.D)
                        ||
                        maze.cells[x, y] == (Directions_Ortho_2D.D | Directions_Ortho_2D.R)
                        )
                    {
                        numCorners++;
                    }
                }
            }
            return(numCorners);
        }
コード例 #9
0
        public static int Num_T_Junctions(this PM_Maze maze)
        {
            int width  = maze.Q_Width();
            int height = maze.Q_Height();

            int num = 0;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    Directions_Ortho_2D dir = maze.Q_Cell_Directions(x, y);
                    if (
                        dir == (Directions_Ortho_2D.Y | Directions_Ortho_2D.L)
                        ||
                        dir == (Directions_Ortho_2D.Y | Directions_Ortho_2D.R)
                        ||
                        dir == (Directions_Ortho_2D.X | Directions_Ortho_2D.U)
                        ||
                        dir == (Directions_Ortho_2D.X | Directions_Ortho_2D.D)
                        )
                    {
                        num++;
                    }
                }
            }
            return(num);
        }
        public static int Cell__Centrality(
            this PM_Maze maze,
            int x,
            int y
            )
        {
            int centrality = 0;
            Directions_Ortho_2D cellDirections = maze.Q_Cell_Directions(x, y);

            if (cellDirections.HasFlag(Directions_Ortho_2D.U))
            {
                centrality++;
            }
            if (cellDirections.HasFlag(Directions_Ortho_2D.D))
            {
                centrality++;
            }
            if (cellDirections.HasFlag(Directions_Ortho_2D.L))
            {
                centrality++;
            }
            if (cellDirections.HasFlag(Directions_Ortho_2D.R))
            {
                centrality++;
            }
            return(centrality);
        }
コード例 #11
0
        public static void Fill_Random_DFS(
            this PM_Maze maze,
            Random rand
            )
        {
            if (maze == null)
            {
                return;
            }
            List <UEdge2i> allPossibleEdges = maze.ConnectedCells_ExpansionEdges_List();

            // temporarily commented out
            allPossibleEdges.Shuffle(rand);

            while (allPossibleEdges.Count > 0)
            {
                UEdge2i edge = allPossibleEdges.Pop_Last_Item();
                if (maze.Q_Is_Cell_Unconnected(edge.exit))
                {
                    maze.OP_AddEdge(edge);
                    List <UEdge2i> newEdges = maze.Cell_ExpansionEdges_List(edge.exit);
                    newEdges.Shuffle(rand);
                    allPossibleEdges.AddRange(newEdges);
                }
            }
        }
コード例 #12
0
        //public static HashSet<PM_Vec2> ReachableCells_Set(
        //    this PM_Maze maze,
        //    PM_Vec2 cell,
        //    HashSet<PM_Vec2> visitedCells
        //    )
        //{
        //    if (visitedCells == null || visitedCells.Count == 0)
        //    {
        //        visitedCells = new HashSet<PM_Vec2>() { cell };
        //    }

        //    HashSet<PM_Vec2> neighbors = maze.Cell_ActiveNeighbors_Set(cell);
        //    foreach (var neighbor in neighbors)
        //    {
        //        if (visitedCells.Contains(neighbor) == false)
        //        {
        //            visitedCells.Add(neighbor);
        //            maze.ReachableCells_Set(neighbor, visitedCells);
        //        }
        //    }

        //    return visitedCells;
        //}

        public static List <Vec2i> ReachableCells_List(
            this PM_Maze maze,
            Vec2i cell,
            List <Vec2i> visitedCells
            )
        {
            if (visitedCells == null || visitedCells.Count == 0)
            {
                visitedCells = new List <Vec2i>()
                {
                    cell
                };
            }

            List <Vec2i> neighbors = maze.Cells_Connected_To_Cell__List(cell);

            foreach (var neighbor in neighbors)
            {
                if (visitedCells.Contains(neighbor) == false)
                {
                    visitedCells.Add(neighbor);
                    maze.ReachableCells_List(neighbor, visitedCells);
                }
            }

            return(visitedCells);
        }
コード例 #13
0
 public static Vec2i Find_SymmetricCell_Over_Y_Axis(
     this PM_Maze maze,
     Vec2i cell
     )
 {
     return(new Vec2i(maze.Q_Width() - 1 - cell.x, cell.y));
 }
コード例 #14
0
        public override void DestroyMaze(
            Random rand,
            PM_Maze maze
            )
        {
            int width  = maze.Q_Width();
            int height = maze.Q_Height();

            bool atleast_one_destroyed = false;

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    double diceRoll = rand.NextDouble();
                    if (diceRoll < DestructionRate)
                    {
                        maze.OP_DeleteCell(x, y);
                        atleast_one_destroyed = true;
                    }
                }
            }

            if (atleast_one_destroyed == false)
            {
                // destroy one...
                int random_x_index = rand.Next(0, width - 1);
                int random_y_index = rand.Next(0, height - 1);
                maze.OP_DeleteCell(random_x_index, random_y_index);
            }
        }
コード例 #15
0
 public static int Num_ReachableCells(
     this PM_Maze maze,
     Vec2i cell
     )
 {
     return(maze.ReachableCells_List(cell, null).Count);
 }
コード例 #16
0
        public static List <UEdge2i> All_InactiveEdges_InBounds_List(
            this PM_Maze maze
            )
        {
            int width  = maze.Q_Width();
            int height = maze.Q_Height();

            List <UEdge2i> inactiveEdges = new List <UEdge2i>();

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    var newEdges = maze.Cell_InactiveEdges_InBounds_List(x, y);
                    foreach (var newEdge in newEdges)
                    {
                        if (inactiveEdges.Contains(newEdge) == false)
                        {
                            inactiveEdges.Add(newEdge);
                        }
                    }
                }
            }
            return(inactiveEdges);
        }
コード例 #17
0
        public static bool IsCyclic(
            this PM_Maze maze
            )
        {
            List <Vec2i> nodes = maze.CellsPositions_All_List();

            // Mark all the vertices as not visited
            // and not part of recursion stack
            HashSet <Vec2i> visitedNodes = new HashSet <Vec2i>();

            // Call the recursive helper function
            // to detect cycle in different DFS trees
            foreach (var node in nodes)
            {
                // Don't recur for u if already visited
                if (visitedNodes.Contains(node) == false)
                {
                    if (IsCyclic_Helper(maze, node, visitedNodes, new Vec2i(-1, -1)))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #18
0
        public static List <UEdge2i> All_Possible_OneWay_Edges_List(
            this PM_Maze maze
            )
        {
            int width  = maze.Q_Width();
            int height = maze.Q_Height();

            List <UEdge2i> edges = new List <UEdge2i>();

            for (int x = 0; x < width; x++)
            {
                for (int y = 0; y < height; y++)
                {
                    Vec2i pos   = new Vec2i(x, y);
                    Vec2i right = pos.To_Right();
                    Vec2i up    = pos.To_Up();

                    if (x < width - 1)
                    {
                        edges.Add(new UEdge2i(pos, right));
                    }
                    if (y < height - 1)
                    {
                        edges.Add(new UEdge2i(pos, up));
                    }
                }
            }

            return(edges);
        }
コード例 #19
0
        public static HashSet <UEdge2i> Cell_ActiveEdges_Set(
            this PM_Maze maze,
            Vec2i pos
            )
        {
            HashSet <UEdge2i> activeEdges = new HashSet <UEdge2i>();

            if (maze.Q_Cell_Directions(pos).HasFlag(Directions_Ortho_2D.U))
            {
                activeEdges.Add(
                    new UEdge2i(pos, pos.To_Up())
                    );
            }
            if (maze.Q_Cell_Directions(pos).HasFlag(Directions_Ortho_2D.D))
            {
                activeEdges.Add(
                    new UEdge2i(pos, pos.To_Down())
                    );
            }
            if (maze.Q_Cell_Directions(pos).HasFlag(Directions_Ortho_2D.L))
            {
                activeEdges.Add(
                    new UEdge2i(pos, pos.To_Left())
                    );
            }
            if (maze.Q_Cell_Directions(pos).HasFlag(Directions_Ortho_2D.R))
            {
                activeEdges.Add(
                    new UEdge2i(pos, pos.To_Right())
                    );
            }
            return(activeEdges);
        }
コード例 #20
0
 public static void LOP_Set_Cell_Directions(
     this PM_Maze maze,
     Vec2i pos,
     Directions_Ortho_2D dir
     )
 {
     maze.LOP_Set_Cell_Directions(pos.x, pos.y, dir);
 }
コード例 #21
0
 public static HashSet <UEdge2i> Cell_ExpansionEdges_Set(
     this PM_Maze maze,
     int x,
     int y
     )
 {
     return(maze.Cell_ExpansionEdges_Set(new Vec2i(x, y)));
 }
コード例 #22
0
 public static HashSet <UEdge2i> Cell_InactiveEdges_InBounds_Set(
     this PM_Maze maze,
     int x,
     int y
     )
 {
     return(maze.Cell_InactiveEdges_InBounds_Set(new Vec2i(x, y)));
 }
コード例 #23
0
 public static Rect2i BoundingRect(
     this PM_Maze maze
     )
 {
     return(new Rect2i(
                new Vec2i(0, 0),
                new Vec2i(maze.Q_Width() - 1, maze.Q_Height() - 1)
                ));
 }
コード例 #24
0
 public static void LLOP_Add_Cell_Directions(
     this PM_Maze maze,
     int x,
     int y,
     Directions_Ortho_2D dir
     )
 {
     maze.cells[x, y] |= dir;
 }
コード例 #25
0
        public override double Evaluate(PM_Maze maze)
        {
            int numNodes   = maze.CellsPositions_All_Set().Count;
            int numCorners = maze.Num_Cells_Corners();

            double percentage = (double)numCorners / (double)numNodes;

            return(percentage);
        }
コード例 #26
0
        public static void OP_DeleteCell(this PM_Maze maze, Vec2i cell)
        {
            HashSet <UEdge2i> cellActiveEdges = maze.Cell_ActiveEdges_Set(cell);

            foreach (UEdge2i edge in cellActiveEdges)
            {
                maze.OP_RemoveEdge(edge);
            }
        }
コード例 #27
0
        public override void DestroyMaze(
            Random rand,
            PM_Maze maze
            )
        {
            Rect2i boundingRect    = maze.BoundingRect();
            Rect2i destructionRect = boundingRect.Random_ContainedRect(rand);

            maze.HOP_DeleteArea(destructionRect);
        }
        public static bool IsCell_DeadEnd(this PM_Maze maze, int x, int y)
        {
            Directions_Ortho_2D cellDirections = maze.Q_Cell_Directions(x, y);

            if (cellDirections.IsSingle() || cellDirections == Directions_Ortho_2D.None)
            {
                return(true);
            }
            return(false);
        }
コード例 #29
0
 public void MutateMaze(
     Random rand,
     PM_Maze maze,
     int currentNumIterations,
     int maxNumIterations
     )
 {
     MazeDestructionMethod.DestroyMaze(rand, maze);
     MazeRepairMethod.RefillMaze(rand, maze);
 }
コード例 #30
0
 public static Vec2i RandomCell(
     this PM_Maze maze,
     Random rand
     )
 {
     return(new Vec2i(
                rand.Next(maze.Q_Width()),
                rand.Next(maze.Q_Height())
                ));
 }