Mazes #155

Merged
StevenRS11 merged 11 commits from mazes into mazes 2014-04-15 11:46:00 +00:00
6 changed files with 206 additions and 131 deletions
Showing only changes of commit d5e5e12cf9 - Show all commits

View File

@@ -18,8 +18,8 @@ public class MazeBuilder
Point3D offset = new Point3D(x - design.width() / 2, y - design.height() - 1, z - design.length() / 2); Point3D offset = new Point3D(x - design.width() / 2, y - design.height() - 1, z - design.length() / 2);
SphereDecayOperation decay = new SphereDecayOperation(random, 0, 0, Block.stoneBrick.blockID, 2); SphereDecayOperation decay = new SphereDecayOperation(random, 0, 0, Block.stoneBrick.blockID, 2);
buildRooms(design.getRoomGraph(), world, offset); buildRooms(design.getLayout(), world, offset);
carveDoorways(design.getRoomGraph(), world, offset, decay, random); carveDoorways(design.getLayout(), world, offset, decay, random);
//placeDoors(design, world, offset); //placeDoors(design, world, offset);
@@ -32,25 +32,25 @@ public class MazeBuilder
//final int DECAY_BOX_SIZE = 8 //final int DECAY_BOX_SIZE = 8
} }
private static void buildRooms(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world, Point3D offset) private static void buildRooms(DirectedGraph<RoomData, DoorwayData> layout, World world, Point3D offset)
{ {
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes()) for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
{ {
PartitionNode room = node.data(); PartitionNode room = node.data().getPartitionNode();
buildBox(world, offset, room.minCorner(), room.maxCorner(), Block.stoneBrick.blockID, 0); buildBox(world, offset, room.minCorner(), room.maxCorner(), Block.stoneBrick.blockID, 0);
} }
} }
private static void carveDoorways(DirectedGraph<PartitionNode, DoorwayData> roomGraph, World world, private static void carveDoorways(DirectedGraph<RoomData, DoorwayData> layout, World world,
Point3D offset, SphereDecayOperation decay, Random random) Point3D offset, SphereDecayOperation decay, Random random)
{ {
char axis; char axis;
Point3D lower; Point3D lower;
DoorwayData doorway; DoorwayData doorway;
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes()) for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
{ {
for (IEdge<PartitionNode, DoorwayData> passage : node.outbound()) for (IEdge<RoomData, DoorwayData> passage : node.outbound())
{ {
doorway = passage.data(); doorway = passage.data();
axis = doorway.axis(); axis = doorway.axis();
@@ -165,7 +165,6 @@ public class MazeBuilder
setBlockDirectly(world, x, y, z, 0, 0); setBlockDirectly(world, x, y, z, 0, 0);
setBlockDirectly(world, x, y + 1, z, 0, 0); setBlockDirectly(world, x, y + 1, z, 0, 0);
} }
private static void buildBox(World world, Point3D offset, Point3D minCorner, Point3D maxCorner, int blockID, int metadata) private static void buildBox(World world, Point3D offset, Point3D minCorner, Point3D maxCorner, int blockID, int metadata)
{ {

View File

@@ -5,16 +5,12 @@ import java.util.ArrayList;
public class MazeDesign public class MazeDesign
{ {
private PartitionNode root; private PartitionNode root;
private DirectedGraph<PartitionNode, DoorwayData> rooms; private DirectedGraph<RoomData, DoorwayData> layout;
private ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores;
private ArrayList<BoundingBox> protectedAreas;
public MazeDesign(PartitionNode root, DirectedGraph<PartitionNode, DoorwayData> rooms, public MazeDesign(PartitionNode root, DirectedGraph<RoomData, DoorwayData> layout)
ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores)
{ {
this.root = root; this.root = root;
this.rooms = rooms; this.layout = layout;
this.cores = cores;
} }
public PartitionNode getRootPartition() public PartitionNode getRootPartition()
@@ -22,19 +18,9 @@ public class MazeDesign
return root; return root;
} }
public DirectedGraph<PartitionNode, DoorwayData> getRoomGraph() public DirectedGraph<RoomData, DoorwayData> getLayout()
{ {
return rooms; return layout;
}
public ArrayList<IGraphNode<PartitionNode, DoorwayData>> getCoreNodes()
{
return cores;
}
public ArrayList<BoundingBox> getProtectedAreas()
{
return protectedAreas;
} }
public int width() public int width()

View File

@@ -25,55 +25,66 @@ public class MazeDesigner
public static MazeDesign generate(Random random) public static MazeDesign generate(Random random)
{ {
// Construct a random binary space partitioning of our maze volume // Construct a random binary space partitioning of our maze volume
PartitionNode root = partitionRooms(MAZE_WIDTH, MAZE_HEIGHT, MAZE_LENGTH, SPLIT_COUNT, random); PartitionNode<RoomData> root = partitionRooms(MAZE_WIDTH, MAZE_HEIGHT, MAZE_LENGTH, SPLIT_COUNT, random);
// List all the leaf nodes of the partition tree, which denote individual rooms // Attach rooms to all the leaf nodes of the partition tree
ArrayList<PartitionNode> partitions = new ArrayList<PartitionNode>(1 << SPLIT_COUNT); ArrayList<RoomData> rooms = new ArrayList<RoomData>(1 << SPLIT_COUNT);
listRoomPartitions(root, partitions); attachRooms(root, rooms);
// Shuffle the list of rooms so that they're not listed in any ordered way in the room graph
// This is the only convenient way of randomizing the maze sections generated later
Collections.shuffle(rooms, random);
// Construct an adjacency graph of the rooms we've carved out. Two rooms are // Construct an adjacency graph of the rooms we've carved out. Two rooms are
// considered adjacent if and only if a doorway could connect them. Their // considered adjacent if and only if a doorway could connect them. Their
// common boundary must be large enough for a doorway. // common boundary must be large enough for a doorway.
DirectedGraph<PartitionNode, DoorwayData> rooms = createRoomGraph(root, partitions, random); DirectedGraph<RoomData, DoorwayData> layout = createRoomGraph(root, rooms, random);
// 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<RoomData> cores = createMazeSections(layout, random);
// Remove unnecessary passages through floors/ceilings and some from the walls // Remove unnecessary passages through floors/ceilings and some from the walls
for (IGraphNode<PartitionNode, DoorwayData> core : cores) for (RoomData core : cores)
{ {
pruneDoorways(core, rooms, random); pruneDoorways(core.getLayoutNode(), layout, random);
} }
return new MazeDesign(root, rooms, cores); return new MazeDesign(root, layout);
} }
private static void listRoomPartitions(PartitionNode node, ArrayList<PartitionNode> partitions) private static void attachRooms(PartitionNode<RoomData> node, ArrayList<RoomData> partitions)
{ {
if (node.isLeaf()) if (node.isLeaf())
{ {
partitions.add(node); partitions.add(new RoomData(node));
} }
else else
{ {
listRoomPartitions(node.leftChild(), partitions); attachRooms(node.leftChild(), partitions);
listRoomPartitions(node.rightChild(), partitions); attachRooms(node.rightChild(), partitions);
} }
} }
private static void removeRoomPartitions(PartitionNode node) private static void removeRoom(RoomData room, DirectedGraph<RoomData, DoorwayData> layout)
{ {
// Remove a node and any of its ancestors that become leaf nodes // Remove the room from the partition tree and from the layout graph.
// Also remove any ancestors that become leaf nodes.
PartitionNode parent; PartitionNode parent;
PartitionNode current; PartitionNode current;
current = node; current = room.getPartitionNode();
while (current != null && current.isLeaf()) while (current != null && current.isLeaf())
{ {
parent = current.parent(); parent = current.parent();
current.remove(); current.remove();
current = parent; current = parent;
} }
// Remove the room from the layout graph
layout.removeNode(room.getLayoutNode());
// Wipe the room's data, as a precaution.
room.clear();
} }
private static PartitionNode partitionRooms(int width, int height, int length, int maxLevels, Random random) private static PartitionNode partitionRooms(int width, int height, int length, int maxLevels, Random random)
@@ -140,35 +151,25 @@ public class MazeDesigner
} }
} }
private static DirectedGraph<PartitionNode, DoorwayData> createRoomGraph(PartitionNode root, ArrayList<PartitionNode> partitions, Random random) private static DirectedGraph<RoomData, DoorwayData> createRoomGraph(PartitionNode<RoomData> root, ArrayList<RoomData> rooms, Random random)
{ {
DirectedGraph<PartitionNode, DoorwayData> roomGraph = new DirectedGraph<PartitionNode, DoorwayData>(); DirectedGraph<RoomData, DoorwayData> layout = new DirectedGraph<RoomData, DoorwayData>();
HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>> roomsToGraph = new HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>>(2 * partitions.size());
// Shuffle the list of rooms so that they're not listed in any ordered way in the room graph
// This is the only convenient way of randomizing the maze sections generated later
Collections.shuffle(partitions, random);
// Add all rooms to a graph // Add all rooms to a graph
// Also add them to a map so we can associate rooms with their graph nodes for (RoomData room : rooms)
// The map is needed for linking graph nodes based on adjacent partitions
for (PartitionNode partition : partitions)
{ {
roomsToGraph.put(partition, roomGraph.addNode(partition)); room.addToLayout(layout);
} }
// Add edges for each room // Add edges for each room
for (IGraphNode<PartitionNode, DoorwayData> node : roomGraph.nodes()) for (IGraphNode<RoomData, DoorwayData> node : layout.nodes())
{ {
findDoorways(node, root, roomsToGraph, roomGraph); findDoorways(node.data(), root, layout);
} }
return layout;
return roomGraph;
} }
private static void findDoorways(IGraphNode<PartitionNode, DoorwayData> roomNode, PartitionNode root, private static void findDoorways(RoomData room, PartitionNode<RoomData> root,
HashMap<PartitionNode, IGraphNode<PartitionNode, DoorwayData>> roomsToGraph, DirectedGraph<RoomData, DoorwayData> layout)
DirectedGraph<PartitionNode, DoorwayData> roomGraph)
{ {
// This function finds rooms adjacent to a specified room that could be connected // This function finds rooms adjacent to a specified room that could be connected
// to it through a doorway. Edges are added to the room graph to denote rooms that // to it through a doorway. Edges are added to the room graph to denote rooms that
@@ -186,7 +187,7 @@ public class MazeDesigner
// there will always be a way to walk from any room to any other room. // there will always be a way to walk from any room to any other room.
boolean[][] detected; boolean[][] detected;
PartitionNode adjacent; PartitionNode<RoomData> adjacent;
int a, b, c; int a, b, c;
int p, q, r; int p, q, r;
@@ -195,11 +196,10 @@ public class MazeDesigner
Point3D otherMin; Point3D otherMin;
Point3D otherMax; Point3D otherMax;
DoorwayData doorway; DoorwayData doorway;
IGraphNode<PartitionNode, DoorwayData> adjacentNode;
PartitionNode room = roomNode.data(); PartitionNode partition = room.getPartitionNode();
Point3D minCorner = room.minCorner(); Point3D minCorner = partition.minCorner();
Point3D maxCorner = room.maxCorner(); Point3D maxCorner = partition.maxCorner();
int minX = minCorner.getX(); int minX = minCorner.getX();
int minY = minCorner.getY(); int minY = minCorner.getY();
@@ -209,9 +209,9 @@ public class MazeDesigner
int maxY = maxCorner.getY(); int maxY = maxCorner.getY();
int maxZ = maxCorner.getZ(); int maxZ = maxCorner.getZ();
int width = room.width(); int width = partition.width();
int height = room.height(); int height = partition.height();
int length = room.length(); int length = partition.length();
if (maxZ < root.maxCorner().getZ()) if (maxZ < root.maxCorner().getZ())
{ {
@@ -247,8 +247,7 @@ public class MazeDesigner
otherMin = new Point3D(minXI, minYI, maxZ); otherMin = new Point3D(minXI, minYI, maxZ);
otherMax = new Point3D(maxXI, maxYI, maxZ + 1); otherMax = new Point3D(maxXI, maxYI, maxZ + 1);
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Z_AXIS); doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Z_AXIS);
adjacentNode = roomsToGraph.get(adjacent); layout.addEdge(room.getLayoutNode(), adjacent.getData().getLayoutNode(), doorway);
roomGraph.addEdge(roomNode, adjacentNode, doorway);
} }
} }
else else
@@ -295,8 +294,7 @@ public class MazeDesigner
otherMin = new Point3D(maxX, minYI, minZI); otherMin = new Point3D(maxX, minYI, minZI);
otherMax = new Point3D(maxX + 1, maxYI, maxZI); otherMax = new Point3D(maxX + 1, maxYI, maxZI);
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.X_AXIS); doorway = new DoorwayData(otherMin, otherMax, DoorwayData.X_AXIS);
adjacentNode = roomsToGraph.get(adjacent); layout.addEdge(room.getLayoutNode(), adjacent.getData().getLayoutNode(), doorway);
roomGraph.addEdge(roomNode, adjacentNode, doorway);
} }
} }
else else
@@ -343,8 +341,7 @@ public class MazeDesigner
otherMin = new Point3D(minXI, maxY, minZI); otherMin = new Point3D(minXI, maxY, minZI);
otherMax = new Point3D(maxXI, maxY + 1, maxZI); otherMax = new Point3D(maxXI, maxY + 1, maxZI);
doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Y_AXIS); doorway = new DoorwayData(otherMin, otherMax, DoorwayData.Y_AXIS);
adjacentNode = roomsToGraph.get(adjacent); layout.addEdge(room.getLayoutNode(), adjacent.getData().getLayoutNode(), doorway);
roomGraph.addEdge(roomNode, adjacentNode, doorway);
} }
} }
else else
@@ -359,7 +356,7 @@ public class MazeDesigner
//Done! //Done!
} }
private static ArrayList<IGraphNode<PartitionNode, DoorwayData>> createMazeSections(DirectedGraph<PartitionNode, DoorwayData> roomGraph, Random random) private static ArrayList<RoomData> createMazeSections(DirectedGraph<RoomData, DoorwayData> layout, Random random)
{ {
// The randomness of the sections generated here hinges on // The randomness of the sections generated here hinges on
// the nodes in the graph being in a random order. We assume // the nodes in the graph being in a random order. We assume
@@ -369,66 +366,68 @@ public class MazeDesigner
final int MIN_SECTION_ROOMS = 5; final int MIN_SECTION_ROOMS = 5;
int distance; int distance;
IGraphNode<PartitionNode, DoorwayData> current; RoomData room;
IGraphNode<PartitionNode, DoorwayData> neighbor; RoomData neighbor;
IGraphNode<RoomData, DoorwayData> current;
ArrayList<IGraphNode<PartitionNode, DoorwayData>> cores = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>(); ArrayList<RoomData> cores = new ArrayList<RoomData>();
ArrayList<IGraphNode<PartitionNode, DoorwayData>> removals = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>(); ArrayList<RoomData> removals = new ArrayList<RoomData>();
ArrayList<IGraphNode<PartitionNode, DoorwayData>> section = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>(); ArrayList<RoomData> section = new ArrayList<RoomData>();
Queue<IGraphNode<PartitionNode, DoorwayData>> ordering = new LinkedList<IGraphNode<PartitionNode, DoorwayData>>(); Queue<RoomData> ordering = new LinkedList<RoomData>();
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<RoomData, DoorwayData> node : layout.nodes())
{ {
// If this node hasn't been visited, then use it as the core of a new section // 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
if (!distances.containsKey(node)) room = node.data();
if (room.getDistance() < 0)
{ {
// 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); room.setDistance(0);
ordering.add(node); ordering.add(room);
section.clear(); section.clear();
while (!ordering.isEmpty()) while (!ordering.isEmpty())
{ {
current = ordering.remove(); room = ordering.remove();
distance = distances.get(current) + 1; distance = room.getDistance() + 1;
if (distance <= MAX_DISTANCE + 1) if (distance <= MAX_DISTANCE + 1)
{ {
section.add(current); section.add(room);
current = room.getLayoutNode();
// Visit neighboring nodes and assign them distances, if they don't // Visit neighboring rooms and assign them distances, if they don't
// have a distance assigned already // have a proper distance assigned already
for (IEdge<PartitionNode, DoorwayData> edge : current.inbound()) for (IEdge<RoomData, DoorwayData> edge : current.inbound())
{ {
neighbor = edge.head(); neighbor = edge.head().data();
if (!distances.containsKey(neighbor)) if (neighbor.getDistance() < 0)
{ {
distances.put(neighbor, distance); neighbor.setDistance(distance);
ordering.add(neighbor); ordering.add(neighbor);
} }
} }
for (IEdge<PartitionNode, DoorwayData> edge : current.outbound()) for (IEdge<RoomData, DoorwayData> edge : current.outbound())
{ {
neighbor = edge.tail(); neighbor = edge.tail().data();
if (!distances.containsKey(neighbor)) if (neighbor.getDistance() < 0)
{ {
distances.put(neighbor, distance); neighbor.setDistance(distance);
ordering.add(neighbor); ordering.add(neighbor);
} }
} }
} }
else else
{ {
removals.add(current); removals.add(room);
break; break;
} }
} }
// List nodes that have a distance of exactly MAX_DISTANCE + 1 // List rooms 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 // We can't remove them immediately because that could break
// the iterator for the graph. // the iterator for the graph.
@@ -440,7 +439,7 @@ public class MazeDesigner
// Check if this section contains enough rooms // Check if this section contains enough rooms
if (section.size() >= MIN_SECTION_ROOMS) if (section.size() >= MIN_SECTION_ROOMS)
{ {
cores.add(node); cores.add(node.data());
} }
else else
{ {
@@ -449,18 +448,17 @@ public class MazeDesigner
} }
} }
// Remove all the nodes that were listed for removal // Remove all the rooms that were listed for removal
// Also remove unused partitions from the partition tree // Also remove unused partitions from the partition tree
for (IGraphNode<PartitionNode, DoorwayData> node : removals) for (RoomData target : removals)
{ {
removeRoomPartitions(node.data()); removeRoom(target, layout);
roomGraph.removeNode(node);
} }
return cores; return cores;
} }
private static void pruneDoorways(IGraphNode<PartitionNode, DoorwayData> core, private static void pruneDoorways(IGraphNode<RoomData, DoorwayData> core,
DirectedGraph<PartitionNode, DoorwayData> rooms, Random random) DirectedGraph<RoomData, DoorwayData> layout, 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
// and we need to remove as many floor doorways as possible while // and we need to remove as many floor doorways as possible while
@@ -478,12 +476,12 @@ public class MazeDesigner
// idea applies for the other doorways, plus some randomness. // idea applies for the other doorways, plus some randomness.
// First, list all nodes in the subgraph // First, list all nodes in the subgraph
IGraphNode<PartitionNode, DoorwayData> current; IGraphNode<RoomData, DoorwayData> current;
IGraphNode<PartitionNode, DoorwayData> neighbor; IGraphNode<RoomData, DoorwayData> neighbor;
Stack<IGraphNode<PartitionNode, DoorwayData>> ordering = new Stack<IGraphNode<PartitionNode, DoorwayData>>(); Stack<IGraphNode<RoomData, DoorwayData>> ordering = new Stack<IGraphNode<RoomData, DoorwayData>>();
ArrayList<IGraphNode<PartitionNode, DoorwayData>> subgraph = new ArrayList<IGraphNode<PartitionNode, DoorwayData>>(64); ArrayList<IGraphNode<RoomData, DoorwayData>> subgraph = new ArrayList<IGraphNode<RoomData, DoorwayData>>(64);
DisjointSet<IGraphNode<PartitionNode, DoorwayData>> components = new DisjointSet<IGraphNode<PartitionNode, DoorwayData>>(128); DisjointSet<IGraphNode<RoomData, DoorwayData>> components = new DisjointSet<IGraphNode<RoomData, DoorwayData>>(128);
ordering.add(core); ordering.add(core);
components.makeSet(core); components.makeSet(core);
@@ -492,7 +490,7 @@ public class MazeDesigner
current = ordering.pop(); current = ordering.pop();
subgraph.add(current); subgraph.add(current);
for (IEdge<PartitionNode, DoorwayData> edge : current.inbound()) for (IEdge<RoomData, DoorwayData> edge : current.inbound())
{ {
neighbor = edge.head(); neighbor = edge.head();
if (components.makeSet(neighbor)) if (components.makeSet(neighbor))
@@ -500,7 +498,7 @@ public class MazeDesigner
ordering.add(neighbor); ordering.add(neighbor);
} }
} }
for (IEdge<PartitionNode, DoorwayData> edge : current.outbound()) for (IEdge<RoomData, DoorwayData> edge : current.outbound())
{ {
neighbor = edge.tail(); neighbor = edge.tail();
if (components.makeSet(neighbor)) if (components.makeSet(neighbor))
@@ -513,12 +511,12 @@ public class MazeDesigner
// Now iterate over the list of nodes and merge their sets // Now iterate over the list of nodes and merge their sets
// We only have to look at outbound edges since inbound edges mirror them // We only have to look at outbound edges since inbound edges mirror them
// Also list any Y_AXIS doorways we come across // Also list any Y_AXIS doorways we come across
ArrayList<IEdge<PartitionNode, DoorwayData>> targets = ArrayList<IEdge<RoomData, DoorwayData>> targets =
new ArrayList<IEdge<PartitionNode, DoorwayData>>(); new ArrayList<IEdge<RoomData, DoorwayData>>();
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph) for (IGraphNode<RoomData, DoorwayData> room : subgraph)
{ {
for (IEdge<PartitionNode, DoorwayData> passage : room.outbound()) for (IEdge<RoomData, DoorwayData> passage : room.outbound())
{ {
if (passage.data().axis() != DoorwayData.Y_AXIS) if (passage.data().axis() != DoorwayData.Y_AXIS)
{ {
@@ -535,11 +533,11 @@ public class MazeDesigner
Collections.shuffle(targets, random); Collections.shuffle(targets, random);
// Merge sets together and remove unnecessary doorways // Merge sets together and remove unnecessary doorways
for (IEdge<PartitionNode, DoorwayData> passage : targets) for (IEdge<RoomData, DoorwayData> passage : targets)
{ {
if (!components.mergeSets(passage.head(), passage.tail())) if (!components.mergeSets(passage.head(), passage.tail()))
{ {
rooms.removeEdge(passage); layout.removeEdge(passage);
} }
} }
@@ -548,13 +546,13 @@ public class MazeDesigner
components.clear(); components.clear();
targets.clear(); targets.clear();
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph) for (IGraphNode<RoomData, DoorwayData> room : subgraph)
{ {
components.makeSet(room); components.makeSet(room);
} }
for (IGraphNode<PartitionNode, DoorwayData> room : subgraph) for (IGraphNode<RoomData, DoorwayData> room : subgraph)
{ {
for (IEdge<PartitionNode, DoorwayData> passage : room.outbound()) for (IEdge<RoomData, DoorwayData> passage : room.outbound())
{ {
if (passage.data().axis() == DoorwayData.Y_AXIS) if (passage.data().axis() == DoorwayData.Y_AXIS)
{ {
@@ -567,11 +565,11 @@ public class MazeDesigner
} }
} }
Collections.shuffle(targets, random); Collections.shuffle(targets, random);
for (IEdge<PartitionNode, DoorwayData> passage : targets) for (IEdge<RoomData, DoorwayData> passage : targets)
{ {
if (!components.mergeSets(passage.head(), passage.tail()) && random.nextBoolean()) if (!components.mergeSets(passage.head(), passage.tail()) && random.nextBoolean())
{ {
rooms.removeEdge(passage); layout.removeEdge(passage);
} }
} }
} }

View File

@@ -0,0 +1,6 @@
package StevenDimDoors.experimental;
public class MazeLinkData
{
}

View File

@@ -2,11 +2,12 @@ package StevenDimDoors.experimental;
import StevenDimDoors.mod_pocketDim.Point3D; import StevenDimDoors.mod_pocketDim.Point3D;
public class PartitionNode extends BoundingBox public class PartitionNode<T> extends BoundingBox
{ {
private PartitionNode parent; private PartitionNode parent;
private PartitionNode leftChild = null; private PartitionNode leftChild = null;
private PartitionNode rightChild = null; private PartitionNode rightChild = null;
private T data = null;
public PartitionNode(int width, int height, int length) public PartitionNode(int width, int height, int length)
{ {
@@ -122,4 +123,14 @@ public class PartitionNode extends BoundingBox
return this; return this;
} }
} }
public void setData(T value)
{
this.data = value;
}
public T getData()
{
return data;
}
} }

View File

@@ -0,0 +1,75 @@
package StevenDimDoors.experimental;
import java.util.ArrayList;
public class RoomData
{
private int distance;
private boolean decayed;
private PartitionNode partitionNode;
private ArrayList<MazeLinkData> inboundLinks;
private ArrayList<MazeLinkData> outboundLinks;
private IGraphNode<RoomData, DoorwayData> layoutNode;
public RoomData(PartitionNode partitionNode)
{
this.partitionNode = partitionNode;
this.inboundLinks = new ArrayList<MazeLinkData>();
this.outboundLinks = new ArrayList<MazeLinkData>();
this.layoutNode = null;
this.distance = -1;
this.decayed = false;
partitionNode.setData(this);
}
public PartitionNode getPartitionNode()
{
return this.partitionNode;
}
public IGraphNode<RoomData, DoorwayData> getLayoutNode()
{
return this.layoutNode;
}
public void addToLayout(DirectedGraph<RoomData, DoorwayData> layout)
{
this.layoutNode = layout.addNode(this);
}
public boolean isDecayed()
{
return decayed;
}
public void setDecayed(boolean value)
{
this.decayed = value;
}
public ArrayList<MazeLinkData> getInboundLinks()
{
return this.inboundLinks;
}
public ArrayList<MazeLinkData> getOutboundLinks()
{
return this.outboundLinks;
}
public int getDistance()
{
return distance;
}
public void setDistance(int value)
{
distance = value;
}
public void clear()
{
partitionNode = null;
layoutNode = null;
}
}