Mazes #117
50
src/main/java/StevenDimDoors/experimental/DoorwayData.java
Normal file
50
src/main/java/StevenDimDoors/experimental/DoorwayData.java
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
package StevenDimDoors.experimental;
|
||||||
|
|
||||||
|
import StevenDimDoors.mod_pocketDim.Point3D;
|
||||||
|
|
||||||
|
public class DoorwayData
|
||||||
|
{
|
||||||
|
public final char X_AXIS = 'X';
|
||||||
|
public final char Y_AXIS = 'Y';
|
||||||
|
public final char Z_AXIS = 'Z';
|
||||||
|
|
||||||
|
private RoomNode head;
|
||||||
|
private RoomNode tail;
|
||||||
|
private Point3D minCorner;
|
||||||
|
private Point3D maxCorner;
|
||||||
|
private char axis;
|
||||||
|
|
||||||
|
public DoorwayData(RoomNode head, RoomNode tail, Point3D minCorner, Point3D maxCorner, char axis)
|
||||||
|
{
|
||||||
|
this.head = head;
|
||||||
|
this.tail = tail;
|
||||||
|
this.minCorner = minCorner;
|
||||||
|
this.maxCorner = maxCorner;
|
||||||
|
this.axis = axis;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoomNode head()
|
||||||
|
{
|
||||||
|
return head;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RoomNode tail()
|
||||||
|
{
|
||||||
|
return tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point3D minCorner()
|
||||||
|
{
|
||||||
|
return minCorner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Point3D maxCorner()
|
||||||
|
{
|
||||||
|
return maxCorner;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char axis()
|
||||||
|
{
|
||||||
|
return axis;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -24,15 +24,15 @@ public class MazeGenerator
|
|||||||
|
|
||||||
public static void generate(World world, int x, int y, int z, Random random)
|
public static void generate(World world, int x, int y, int z, Random random)
|
||||||
{
|
{
|
||||||
SpatialNode root = partitionRooms(ROOT_WIDTH, ROOT_HEIGHT, ROOT_LENGTH, SPLIT_COUNT, random);
|
PartitionNode root = partitionRooms(ROOT_WIDTH, ROOT_HEIGHT, ROOT_LENGTH, SPLIT_COUNT, random);
|
||||||
// Collect all the leaf nodes by performing a tree traversal
|
// Collect all the leaf nodes by performing a tree traversal
|
||||||
ArrayList<SpatialNode> rooms = new ArrayList<SpatialNode>(1 << SPLIT_COUNT);
|
ArrayList<PartitionNode> rooms = new ArrayList<PartitionNode>(1 << SPLIT_COUNT);
|
||||||
listRooms(root, rooms);
|
listRooms(root, rooms);
|
||||||
removeRandomRooms(rooms, random);
|
removeRandomRooms(rooms, random);
|
||||||
buildRooms(root, world, new Point3D(x - ROOT_WIDTH / 2, y - ROOT_HEIGHT - 1, z - ROOT_WIDTH / 2));
|
buildRooms(root, world, new Point3D(x - ROOT_WIDTH / 2, y - ROOT_HEIGHT - 1, z - ROOT_WIDTH / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void listRooms(SpatialNode node, ArrayList<SpatialNode> rooms)
|
private static void listRooms(PartitionNode node, ArrayList<PartitionNode> rooms)
|
||||||
{
|
{
|
||||||
if (node.isLeaf())
|
if (node.isLeaf())
|
||||||
{
|
{
|
||||||
@@ -45,7 +45,7 @@ public class MazeGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void removeRandomRooms(ArrayList<SpatialNode> rooms, Random random)
|
private static void removeRandomRooms(ArrayList<PartitionNode> rooms, Random random)
|
||||||
{
|
{
|
||||||
// Randomly remove a fraction of the rooms
|
// Randomly remove a fraction of the rooms
|
||||||
Collections.shuffle(rooms, random);
|
Collections.shuffle(rooms, random);
|
||||||
@@ -56,11 +56,11 @@ public class MazeGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void removeRoom(SpatialNode node)
|
private static void removeRoom(PartitionNode node)
|
||||||
{
|
{
|
||||||
// Remove a node and any of its ancestors that become leaf nodes
|
// Remove a node and any of its ancestors that become leaf nodes
|
||||||
SpatialNode parent;
|
PartitionNode parent;
|
||||||
SpatialNode current;
|
PartitionNode current;
|
||||||
|
|
||||||
current = node;
|
current = node;
|
||||||
while (current != null && current.isLeaf())
|
while (current != null && current.isLeaf())
|
||||||
@@ -71,14 +71,14 @@ public class MazeGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static SpatialNode 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)
|
||||||
{
|
{
|
||||||
SpatialNode root = new SpatialNode(width, height, length);
|
PartitionNode root = new PartitionNode(width, height, length);
|
||||||
splitByRandomX(root, maxLevels, random);
|
splitByRandomX(root, maxLevels, random);
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void splitByRandomX(SpatialNode node, int levels, Random random)
|
private static void splitByRandomX(PartitionNode node, int levels, Random random)
|
||||||
{
|
{
|
||||||
if (node.width() >= 2 * MIN_SIDE)
|
if (node.width() >= 2 * MIN_SIDE)
|
||||||
{
|
{
|
||||||
@@ -97,7 +97,7 @@ public class MazeGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void splitByRandomZ(SpatialNode node, int levels, Random random)
|
private static void splitByRandomZ(PartitionNode node, int levels, Random random)
|
||||||
{
|
{
|
||||||
if (node.length() >= 2 * MIN_SIDE)
|
if (node.length() >= 2 * MIN_SIDE)
|
||||||
{
|
{
|
||||||
@@ -116,7 +116,7 @@ public class MazeGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void splitByRandomY(SpatialNode node, int levels, Random random)
|
private static void splitByRandomY(PartitionNode node, int levels, Random random)
|
||||||
{
|
{
|
||||||
if (node.height() >= 2 * MIN_HEIGHT)
|
if (node.height() >= 2 * MIN_HEIGHT)
|
||||||
{
|
{
|
||||||
@@ -135,7 +135,7 @@ public class MazeGenerator
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildRooms(SpatialNode node, World world, Point3D offset)
|
private static void buildRooms(PartitionNode node, World world, Point3D offset)
|
||||||
{
|
{
|
||||||
if (node.isLeaf())
|
if (node.isLeaf())
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,22 +2,22 @@ package StevenDimDoors.experimental;
|
|||||||
|
|
||||||
import StevenDimDoors.mod_pocketDim.Point3D;
|
import StevenDimDoors.mod_pocketDim.Point3D;
|
||||||
|
|
||||||
public class SpatialNode
|
public class PartitionNode
|
||||||
{
|
{
|
||||||
private Point3D minCorner;
|
private Point3D minCorner;
|
||||||
private Point3D maxCorner;
|
private Point3D maxCorner;
|
||||||
private SpatialNode parent;
|
private PartitionNode parent;
|
||||||
private SpatialNode leftChild = null;
|
private PartitionNode leftChild = null;
|
||||||
private SpatialNode rightChild = null;
|
private PartitionNode rightChild = null;
|
||||||
|
|
||||||
public SpatialNode(int width, int height, int length)
|
public PartitionNode(int width, int height, int length)
|
||||||
{
|
{
|
||||||
parent = null;
|
parent = null;
|
||||||
minCorner = new Point3D(0, 0, 0);
|
minCorner = new Point3D(0, 0, 0);
|
||||||
maxCorner = new Point3D(width - 1, height - 1, length - 1);
|
maxCorner = new Point3D(width - 1, height - 1, length - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SpatialNode(SpatialNode parent, Point3D minCorner, Point3D maxCorner)
|
private PartitionNode(PartitionNode parent, Point3D minCorner, Point3D maxCorner)
|
||||||
{
|
{
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
this.minCorner = minCorner;
|
this.minCorner = minCorner;
|
||||||
@@ -44,12 +44,12 @@ public class SpatialNode
|
|||||||
return (leftChild == null && rightChild == null);
|
return (leftChild == null && rightChild == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpatialNode leftChild()
|
public PartitionNode leftChild()
|
||||||
{
|
{
|
||||||
return leftChild;
|
return leftChild;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpatialNode rightChild()
|
public PartitionNode rightChild()
|
||||||
{
|
{
|
||||||
return rightChild;
|
return rightChild;
|
||||||
}
|
}
|
||||||
@@ -64,7 +64,7 @@ public class SpatialNode
|
|||||||
return maxCorner;
|
return maxCorner;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpatialNode parent()
|
public PartitionNode parent()
|
||||||
{
|
{
|
||||||
return parent;
|
return parent;
|
||||||
}
|
}
|
||||||
@@ -79,8 +79,8 @@ public class SpatialNode
|
|||||||
{
|
{
|
||||||
throw new IllegalArgumentException("The specified cutting plane is invalid.");
|
throw new IllegalArgumentException("The specified cutting plane is invalid.");
|
||||||
}
|
}
|
||||||
leftChild = new SpatialNode(this, minCorner, new Point3D(rightStart - 1, maxCorner.getY(), maxCorner.getZ()));
|
leftChild = new PartitionNode(this, minCorner, new Point3D(rightStart - 1, maxCorner.getY(), maxCorner.getZ()));
|
||||||
rightChild = new SpatialNode(this, new Point3D(rightStart, minCorner.getY(), minCorner.getZ()), maxCorner);
|
rightChild = new PartitionNode(this, new Point3D(rightStart, minCorner.getY(), minCorner.getZ()), maxCorner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void splitByY(int rightStart)
|
public void splitByY(int rightStart)
|
||||||
@@ -93,8 +93,8 @@ public class SpatialNode
|
|||||||
{
|
{
|
||||||
throw new IllegalArgumentException("The specified cutting plane is invalid.");
|
throw new IllegalArgumentException("The specified cutting plane is invalid.");
|
||||||
}
|
}
|
||||||
leftChild = new SpatialNode(this, minCorner, new Point3D(maxCorner.getX(), rightStart - 1, maxCorner.getZ()));
|
leftChild = new PartitionNode(this, minCorner, new Point3D(maxCorner.getX(), rightStart - 1, maxCorner.getZ()));
|
||||||
rightChild = new SpatialNode(this, new Point3D(minCorner.getX(), rightStart, minCorner.getZ()), maxCorner);
|
rightChild = new PartitionNode(this, new Point3D(minCorner.getX(), rightStart, minCorner.getZ()), maxCorner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void splitByZ(int rightStart)
|
public void splitByZ(int rightStart)
|
||||||
@@ -107,8 +107,8 @@ public class SpatialNode
|
|||||||
{
|
{
|
||||||
throw new IllegalArgumentException("The specified cutting plane is invalid.");
|
throw new IllegalArgumentException("The specified cutting plane is invalid.");
|
||||||
}
|
}
|
||||||
leftChild = new SpatialNode(this, minCorner, new Point3D(maxCorner.getX(), maxCorner.getY(), rightStart - 1));
|
leftChild = new PartitionNode(this, minCorner, new Point3D(maxCorner.getX(), maxCorner.getY(), rightStart - 1));
|
||||||
rightChild = new SpatialNode(this, new Point3D(minCorner.getX(), minCorner.getY(), rightStart), maxCorner);
|
rightChild = new PartitionNode(this, new Point3D(minCorner.getX(), minCorner.getY(), rightStart), maxCorner);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove()
|
public void remove()
|
||||||
56
src/main/java/StevenDimDoors/experimental/RoomNode.java
Normal file
56
src/main/java/StevenDimDoors/experimental/RoomNode.java
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package StevenDimDoors.experimental;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class RoomNode
|
||||||
|
{
|
||||||
|
private ArrayList<DoorwayData> outbound;
|
||||||
|
private ArrayList<DoorwayData> inbound;
|
||||||
|
private PartitionNode bounds;
|
||||||
|
private int distance;
|
||||||
|
private boolean visited;
|
||||||
|
|
||||||
|
public RoomNode(PartitionNode bounds)
|
||||||
|
{
|
||||||
|
this.bounds = bounds;
|
||||||
|
this.distance = 0;
|
||||||
|
this.visited = false;
|
||||||
|
this.outbound = new ArrayList<DoorwayData>();
|
||||||
|
this.inbound = new ArrayList<DoorwayData>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int distance()
|
||||||
|
{
|
||||||
|
return distance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isVisited()
|
||||||
|
{
|
||||||
|
return visited;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistance(int value)
|
||||||
|
{
|
||||||
|
distance = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisited(boolean value)
|
||||||
|
{
|
||||||
|
visited = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PartitionNode bounds()
|
||||||
|
{
|
||||||
|
return bounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInboundDoorway(DoorwayData data)
|
||||||
|
{
|
||||||
|
inbound.add(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOutboundDoorway(DoorwayData data)
|
||||||
|
{
|
||||||
|
outbound.add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user