I derped. Oh well. #122

Merged
StevenRS11 merged 18 commits from mazes into master 2014-01-04 07:15:16 +00:00
2 changed files with 81 additions and 15 deletions
Showing only changes of commit a9f0bc5069 - Show all commits

View File

@@ -1,5 +1,7 @@
package StevenDimDoors.experimental;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Random;
import net.minecraft.block.Block;
@@ -13,18 +15,60 @@ public class MazeGenerator
{
public static final int ROOT_WIDTH = 40;
public static final int ROOT_LENGTH = 40;
public static final int ROOT_HEIGHT = 19;
public static final int ROOT_HEIGHT = 20;
private static final int MIN_HEIGHT = 4;
private static final int MIN_SIDE = 3;
private static final int SPLIT_COUNT = 8;
private static final int SPLIT_COUNT = 9;
private MazeGenerator() { }
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);
// Collect all the leaf nodes by performing a tree traversal
ArrayList<SpatialNode> rooms = new ArrayList<SpatialNode>(1 << SPLIT_COUNT);
listRooms(root, rooms);
removeRandomRooms(rooms, random);
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)
{
if (node.isLeaf())
{
rooms.add(node);
}
else
{
listRooms(node.leftChild(), rooms);
listRooms(node.rightChild(), rooms);
}
}
private static void removeRandomRooms(ArrayList<SpatialNode> 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(SpatialNode node)
{
// Remove a node and any of its ancestors that become leaf nodes
SpatialNode parent;
SpatialNode current;
current = node;
while (current != null && current.isLeaf())
{
parent = current.parent();
current.remove();
current = parent;
}
}
private static SpatialNode partitionRooms(int width, int height, int length, int maxLevels, Random random)
@@ -99,7 +143,9 @@ public class MazeGenerator
}
else
{
if (node.leftChild() != null)
buildRooms(node.leftChild(), world, offset);
if (node.rightChild() != null)
buildRooms(node.rightChild(), world, offset);
}
}

View File

@@ -6,17 +6,20 @@ public class SpatialNode
{
private Point3D minCorner;
private Point3D maxCorner;
private SpatialNode parent;
private SpatialNode leftChild = null;
private SpatialNode rightChild = null;
public SpatialNode(int width, int height, int length)
{
parent = null;
minCorner = new Point3D(0, 0, 0);
maxCorner = new Point3D(width - 1, height - 1, length - 1);
}
private SpatialNode(Point3D minCorner, Point3D maxCorner)
private SpatialNode(SpatialNode parent, Point3D minCorner, Point3D maxCorner)
{
this.parent = parent;
this.minCorner = minCorner;
this.maxCorner = maxCorner;
}
@@ -38,7 +41,7 @@ public class SpatialNode
public boolean isLeaf()
{
return (leftChild == null);
return (leftChild == null && rightChild == null);
}
public SpatialNode leftChild()
@@ -61,9 +64,14 @@ public class SpatialNode
return maxCorner;
}
public SpatialNode parent()
{
return parent;
}
public void splitByX(int rightStart)
{
if (leftChild != null)
if (!this.isLeaf())
{
throw new IllegalStateException("This node has already been split.");
}
@@ -71,13 +79,13 @@ public class SpatialNode
{
throw new IllegalArgumentException("The specified cutting plane is invalid.");
}
leftChild = new SpatialNode(minCorner, new Point3D(rightStart - 1, maxCorner.getY(), maxCorner.getZ()));
rightChild = new SpatialNode(new Point3D(rightStart, minCorner.getY(), minCorner.getZ()), maxCorner);
leftChild = new SpatialNode(this, minCorner, new Point3D(rightStart - 1, maxCorner.getY(), maxCorner.getZ()));
rightChild = new SpatialNode(this, new Point3D(rightStart, minCorner.getY(), minCorner.getZ()), maxCorner);
}
public void splitByY(int rightStart)
{
if (leftChild != null)
if (!this.isLeaf())
{
throw new IllegalStateException("This node has already been split.");
}
@@ -85,13 +93,13 @@ public class SpatialNode
{
throw new IllegalArgumentException("The specified cutting plane is invalid.");
}
leftChild = new SpatialNode(minCorner, new Point3D(maxCorner.getX(), rightStart - 1, maxCorner.getZ()));
rightChild = new SpatialNode(new Point3D(minCorner.getX(), rightStart, minCorner.getZ()), maxCorner);
leftChild = new SpatialNode(this, minCorner, new Point3D(maxCorner.getX(), rightStart - 1, maxCorner.getZ()));
rightChild = new SpatialNode(this, new Point3D(minCorner.getX(), rightStart, minCorner.getZ()), maxCorner);
}
public void splitByZ(int rightStart)
{
if (leftChild != null)
if (!this.isLeaf())
{
throw new IllegalStateException("This node has already been split.");
}
@@ -99,7 +107,19 @@ public class SpatialNode
{
throw new IllegalArgumentException("The specified cutting plane is invalid.");
}
leftChild = new SpatialNode(minCorner, new Point3D(maxCorner.getX(), maxCorner.getY(), rightStart - 1));
rightChild = new SpatialNode(new Point3D(minCorner.getX(), minCorner.getY(), rightStart), maxCorner);
leftChild = new SpatialNode(this, minCorner, new Point3D(maxCorner.getX(), maxCorner.getY(), rightStart - 1));
rightChild = new SpatialNode(this, new Point3D(minCorner.getX(), minCorner.getY(), rightStart), maxCorner);
}
public void remove()
{
if (parent != null)
{
if (parent.leftChild == this)
parent.leftChild = null;
else
parent.rightChild = null;
parent = null;
}
}
}