From 906faf44eb338d05c2f883295a7dcecc8ce5c72e Mon Sep 17 00:00:00 2001 From: SenseiKiwi Date: Sun, 13 Apr 2014 16:17:42 -0400 Subject: [PATCH] Tweaked Maze Section Generation Tweaked maze section generation to use a random MAX_DISTANCE for including rooms in a section. Also changed the code to perform room removals as sections are processed rather than deferring them to the end. Deferring removals would cause the algorithm to detect holes from rooms that were going to be removed. This made section generation much stricter than necessary. --- .../experimental/MazeDesigner.java | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/main/java/StevenDimDoors/experimental/MazeDesigner.java b/src/main/java/StevenDimDoors/experimental/MazeDesigner.java index 0026303..8707d46 100644 --- a/src/main/java/StevenDimDoors/experimental/MazeDesigner.java +++ b/src/main/java/StevenDimDoors/experimental/MazeDesigner.java @@ -351,7 +351,7 @@ public class MazeDesigner // neighboring rooms are added until the necessary space is found or the // search space is exhausted. - final int MAX_DISTANCE = 2; + final int MAX_DISTANCE = 2 + random.nextInt(2); final int MIN_SECTION_ROOMS = 5; final int MIN_SECTION_CAPACITY = 2; @@ -363,18 +363,27 @@ public class MazeDesigner IGraphNode roomNode; ArrayList cores = new ArrayList(); - ArrayList removals = new ArrayList(); ArrayList section = new ArrayList(); + ArrayList> nodes = new ArrayList>(layout.nodeCount()); Queue ordering = new LinkedList(); - // Repeatedly generate sections until all nodes have been visited + // List all graph nodes so that we can iterate over this list instead + // of using the graph's iterator. That avoids the risk of breaking + // the graph's iterator during removals. for (IGraphNode node : layout.nodes()) + { + nodes.add(node); + } + + // Repeatedly generate sections until all nodes have been visited + for (IGraphNode node : nodes) { // If this room hasn't been visited (distance = -1), then use it as the core of a new section - // Otherwise, ignore it, since it was already processed + // Otherwise, ignore it, since it was already processed. Also make sure to check that room + // isn't null, which happens if the room was removed previously. room = node.data(); - if (room.getDistance() < 0) + if (room != null && room.getDistance() < 0) { // Perform a breadth-first search to tag surrounding nodes with distances ordering.add(room); @@ -427,13 +436,10 @@ public class MazeDesigner // The remaining rooms in the ordering are those that are at the // frontier of structure. They must be removed to create a gap - // between this section and other sections. But we can't remove - // the rooms immediately because that could break the iterator - // for the graph. - if (!ordering.isEmpty()) + // between this section and other sections. + while (!ordering.isEmpty()) { - removals.addAll(ordering); - ordering.clear(); + ordering.remove().remove(); } // Check if this section contains enough rooms and capacity for doors @@ -443,16 +449,14 @@ public class MazeDesigner } else { - removals.addAll(section); + // Discard the whole section + for (RoomData target : section) + { + target.remove(); + } } } } - - // Remove all the rooms that were listed for removal - for (RoomData target : removals) - { - target.remove(); - } return cores; } @@ -581,8 +585,8 @@ public class MazeDesigner { // We have 4 objectives here... // 1. Place the entrance to the maze - // 2. Place internal links connecting the different sections of the maze - // 3. Place links to other dungeons + // 2. Place links to other dungeons + // 3. Place internal links connecting the different sections of the maze // 4. Place more internal links to confuse people // We need to start by counting the door capacity of each section and @@ -609,6 +613,7 @@ public class MazeDesigner // The next task is to place internal links. These links must connect // the different maze sections to create a strongly connected graph. + } private static int listLinkRooms(IGraphNode core,