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); }
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)); }
public static List <UEdge2i> Cell_ActiveEdges_List( this PM_Maze maze, int x, int y) { return(maze.Cell_ActiveEdges_List(new Vec2i(x, y))); }
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); }
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); }
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); }
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); }
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); }
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); } } }
//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); }
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)); }
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); } }
public static int Num_ReachableCells( this PM_Maze maze, Vec2i cell ) { return(maze.ReachableCells_List(cell, null).Count); }
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); }
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); }
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); }
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); }
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); }
public static HashSet <UEdge2i> Cell_ExpansionEdges_Set( this PM_Maze maze, int x, int y ) { return(maze.Cell_ExpansionEdges_Set(new Vec2i(x, y))); }
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))); }
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) )); }
public static void LLOP_Add_Cell_Directions( this PM_Maze maze, int x, int y, Directions_Ortho_2D dir ) { maze.cells[x, y] |= dir; }
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); }
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); } }
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); }
public void MutateMaze( Random rand, PM_Maze maze, int currentNumIterations, int maxNumIterations ) { MazeDestructionMethod.DestroyMaze(rand, maze); MazeRepairMethod.RefillMaze(rand, maze); }
public static Vec2i RandomCell( this PM_Maze maze, Random rand ) { return(new Vec2i( rand.Next(maze.Q_Width()), rand.Next(maze.Q_Height()) )); }