Mazes #119

Merged
StevenRS11 merged 10 commits from mazes into mazes 2013-12-31 00:07:52 +00:00
2 changed files with 44 additions and 5 deletions
Showing only changes of commit 70ae2fd407 - Show all commits

View File

@@ -126,4 +126,9 @@ public class DisjointSet<T>
return (firstRoot == secondRoot); return (firstRoot == secondRoot);
} }
} }
public void clear()
{
mapping.clear();
}
} }

View File

@@ -39,10 +39,10 @@ public class MazeDesigner
// Cut out random subgraphs from the adjacency graph // Cut out random subgraphs from the adjacency graph
ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores = createMazeSections(rooms, random); ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores = createMazeSections(rooms, random);
// Remove unnecessary passages through floors/ceilings // Remove unnecessary passages through floors/ceilings and some from the walls
for (IGraphNode<PartitionNode, DoorwayData> core : cores) for (IGraphNode<PartitionNode, DoorwayData> core : cores)
{ {
minimizeVerticalPassages(core, rooms, random); pruneDoorways(core, rooms, random);
} }
return new MazeDesign(root, rooms, cores); return new MazeDesign(root, rooms, cores);
@@ -459,7 +459,7 @@ public class MazeDesigner
return cores; return cores;
} }
private static void minimizeVerticalPassages(IGraphNode<PartitionNode, DoorwayData> core, private static void pruneDoorways(IGraphNode<PartitionNode, DoorwayData> core,
DirectedGraph<PartitionNode, DoorwayData> rooms, Random random) DirectedGraph<PartitionNode, DoorwayData> rooms, Random random)
{ {
// We receive a node for one of the rooms in a section of the maze // We receive a node for one of the rooms in a section of the maze
@@ -467,13 +467,15 @@ public class MazeDesigner
// still allowing any room to be reachable from any other room. // still allowing any room to be reachable from any other room.
// In technical terms, we receive a node from a connected subgraph // In technical terms, we receive a node from a connected subgraph
// and we need to remove as many Y_AXIS-type edges as possible while // and we need to remove as many Y_AXIS-type edges as possible while
// preserving connectedness. // preserving connectedness. We also want to randomly remove some of
// the other doorways without breaking connectedness.
// An efficient solution is to assign nodes to disjoint sets based // An efficient solution is to assign nodes to disjoint sets based
// on their components, ignoring all Y_AXIS edges, then iterate over // on their components, ignoring all Y_AXIS edges, then iterate over
// a list of those edges and remove them if they connect two nodes // a list of those edges and remove them if they connect two nodes
// in the same set. Otherwise, merge their sets and keep the edge. // in the same set. Otherwise, merge their sets and keep the edge.
// This is similar to algorithms for spanning trees. // This is similar to algorithms for spanning trees. The same
// idea applies for the other doorways with some chance added.
// First, list all nodes in the subgraph // First, list all nodes in the subgraph
IGraphNode<PartitionNode, DoorwayData> current; IGraphNode<PartitionNode, DoorwayData> current;
@@ -540,6 +542,38 @@ public class MazeDesigner
rooms.removeEdge(passage); rooms.removeEdge(passage);
} }
} }
// Repeat the pruning process with X_AXIS and Z_AXIS doorways
// In this case, unnecessary edges might be kept at random
components.clear();
targets.clear();
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph)
{
components.makeSet(room);
}
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph)
{
for (IEdge<PartitionNode, DoorwayData> passage : room.outbound())
{
if (passage.data().axis() == DoorwayData.Y_AXIS)
{
components.mergeSets(passage.head(), passage.tail());
}
else
{
targets.add(passage);
}
}
}
Collections.shuffle(targets, random);
for (IEdge<PartitionNode, DoorwayData> passage : targets)
{
if (!components.mergeSets(passage.head(), passage.tail()) && random.nextBoolean())
{
rooms.removeEdge(passage);
}
}
} }
} }