Mazes #119

Merged
StevenRS11 merged 10 commits from mazes into mazes 2013-12-31 00:07:52 +00:00
Showing only changes of commit 22ab4e3639 - Show all commits

View File

@@ -58,17 +58,6 @@ public class MazeGenerator
listRoomPartitions(node.rightChild(), partitions); listRoomPartitions(node.rightChild(), partitions);
} }
} }
private static void removeRandomRooms(ArrayList<PartitionNode> rooms, Random random)
{
// Randomly remove a fraction of the rooms
Collections.shuffle(rooms, random);
int remaining = rooms.size() / 2;
for (int k = rooms.size() - 1; k >= remaining; k--)
{
removeRoom(rooms.remove(k));
}
}
private static void removeRoom(PartitionNode node) private static void removeRoom(PartitionNode node)
{ {
@@ -375,35 +364,31 @@ public class MazeGenerator
// that was handled in a previous step! // that was handled in a previous step!
final int MAX_DISTANCE = 2; final int MAX_DISTANCE = 2;
final int MIN_SECTION_ROOMS = 5;
int distance; int distance;
IGraphNode<PartitionNode, DoorwayData> current; IGraphNode<PartitionNode, DoorwayData> current;
IGraphNode<PartitionNode, DoorwayData> neighbor; IGraphNode<PartitionNode, DoorwayData> neighbor;
ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>(); ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>();
ArrayList<IGraphNode<PartitionNode, DoorwayData>> removals = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>();
ArrayList<IGraphNode<PartitionNode, DoorwayData>> section = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>();
Queue<IGraphNode<PartitionNode, DoorwayData>> ordering = new LinkedList<IGraphNode<PartitionNode, DoorwayData>>(); Queue<IGraphNode<PartitionNode, DoorwayData>> ordering = new LinkedList<IGraphNode<PartitionNode, DoorwayData>>();
HashMap<IGraphNode<PartitionNode, DoorwayData>, Integer> distances = new HashMap<IGraphNode<PartitionNode, DoorwayData>, Integer>(); HashMap<IGraphNode<PartitionNode, DoorwayData>, Integer> distances = new HashMap<IGraphNode<PartitionNode, DoorwayData>, Integer>();
// Repeatedly generate sections until all nodes have been visited // Repeatedly generate sections until all nodes have been visited
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes()) for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes())
{ {
// If this node has an indegree and outdegree of 0, then it has no neighbors,
// which means it could not have been visited. This could happen if its neighbors
// were pruned away before. Single rooms look weird, so remove it.
if (node.indegree() == 0 && node.outdegree() == 0)
{
roomGraph.removeNode(node);
}
// If this node hasn't been visited, then use it as the core of a new section // If this node hasn't been visited, then use it as the core of a new section
// Otherwise, ignore it, since it already belongs to a section // Otherwise, ignore it, since it was already processed
else if (!distances.containsKey(node)) if (!distances.containsKey(node))
{ {
cores.add(node);
// Perform a breadth-first search to tag surrounding nodes with distances // Perform a breadth-first search to tag surrounding nodes with distances
distances.put(node, 0); distances.put(node, 0);
ordering.add(node); ordering.add(node);
section.clear();
while (!ordering.isEmpty()) while (!ordering.isEmpty())
{ {
current = ordering.remove(); current = ordering.remove();
@@ -411,6 +396,8 @@ public class MazeGenerator
if (distance <= MAX_DISTANCE + 1) if (distance <= MAX_DISTANCE + 1)
{ {
section.add(current);
// Visit neighboring nodes and assign them distances, if they don't // Visit neighboring nodes and assign them distances, if they don't
// have a distance assigned already // have a distance assigned already
for (IEdge<PartitionNode, DoorwayData> edge : current.inbound()) for (IEdge<PartitionNode, DoorwayData> edge : current.inbound())
@@ -434,19 +421,37 @@ public class MazeGenerator
} }
else else
{ {
roomGraph.removeNode(current); removals.add(current);
break; break;
} }
} }
// Remove all nodes that have a distance of exactly MAX_DISTANCE + 1 // List nodes that have a distance of exactly MAX_DISTANCE + 1
// Those are precisely the nodes that remain in the queue // Those are precisely the nodes that remain in the queue
// We can't remove them immediately because that could break
// the iterator for the graph.
while (!ordering.isEmpty()) while (!ordering.isEmpty())
{ {
roomGraph.removeNode( ordering.remove() ); removals.add(ordering.remove());
}
// Check if this section contains enough rooms
if (section.size() >= MIN_SECTION_ROOMS)
{
cores.add(node);
}
else
{
removals.addAll(section);
} }
} }
} }
// Remove all the nodes that were listed for removal
for (IGraphNode<PartitionNode, DoorwayData> node : removals)
{
roomGraph.removeNode(node);
}
return cores; return cores;
} }