Last active
August 29, 2015 14:12
-
-
Save JonRurka/80a3ca727179f790dc59 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private enum Direction{ | |
N ((byte)1), | |
W ((byte)2); | |
private final byte index; | |
Direction(byte _index){ | |
index = _index; | |
} | |
public byte getIndex(){ | |
return index; | |
} | |
} | |
public final class Maze { | |
Stack s_stack; | |
Random rand; | |
public int MSizeX; | |
public int MSizeY; | |
public int MSizeZ; | |
public int[] maze_base; | |
public byte[][] maze_data; | |
private int iSmooth; | |
// --- Generating --- | |
public void GenerateMaze(int sizeX, int sizeY, int sizeZ, int seed, int smoothness){ | |
iSmooth = smoothness; | |
MSizeX = sizeX; | |
MSizeY = sizeY; | |
MSizeZ = sizeZ; | |
maze_base = new int[MSizeX * MSizeZ]; | |
maze_data = new byte[MSizeX][MSizeZ]; | |
s_stack = new Stack(); | |
rand = new Random(seed); | |
MazeInit(rand); | |
cMazeState state = new cMazeState(rand.nextInt() % MSizeX, rand.nextInt() % MSizeZ, 0); | |
analyze_cell(state, rand); | |
} | |
void analyze_cell(cMazeState s, Random r){ | |
boolean bEnd = false, found; | |
int indexSrc, indexDest, tDir = 0, prevDir = 0; | |
while(true){ | |
if (s.dir == 15){ | |
while (s.dir == 15){ | |
s = (cMazeState)s_stack.pop(); | |
if (s == null){ | |
bEnd = true; | |
break; | |
} | |
} | |
if (bEnd == true) break; | |
} | |
else{ | |
try { | |
do{ | |
prevDir = tDir; | |
tDir = (int)Math.pow(2, r.nextInt() % 4); | |
if ((r.nextInt() % 32) < iSmooth) | |
if ((s.dir & prevDir) == 0) | |
tDir = prevDir; | |
if ((s.dir & tDir) != 0) | |
found = true; | |
else | |
found = false; | |
} while (found == true && s.dir != 15); | |
s.dir |= tDir; | |
indexSrc = cell_index(s.x, s.z); | |
// Dir W | |
if (tDir == 1 && s.x > 0){ | |
indexDest = cell_index(s.x - 1, s.z); | |
if (base_cell(indexSrc) != base_cell(indexDest)){ | |
merge(indexSrc, indexDest); | |
maze_data[s.x][s.z] |= Direction.W.getIndex(); | |
s_stack.push(new cMazeState(s)); | |
s.x -= 1; s.dir = 0; | |
} | |
} | |
// Dir E | |
if (tDir == 2 && s.x < MSizeX - 1){ | |
indexDest = cell_index(s.x + 1, s.z); | |
if (base_cell(indexSrc) != base_cell(indexDest)){ | |
merge(indexSrc, indexDest); | |
maze_data[s.x + 1][s.z] |= Direction.W.getIndex(); | |
s_stack.push(new cMazeState(s)); | |
s.x += 1; s.dir = 0; | |
} | |
} | |
// Dir N | |
if (tDir == 4 && s.z > 0){ | |
indexDest = cell_index(s.x, s.z - 1); | |
if (base_cell(indexSrc) != base_cell(indexDest)){ | |
merge(indexSrc, indexDest); | |
maze_data[s.x][s.z] |= Direction.N.getIndex(); | |
s_stack.push(new cMazeState(s)); | |
s.z -= 1; s.dir = 0; | |
} | |
} | |
// Dir S | |
if (tDir == 8 && s.z < MSizeZ - 1){ | |
indexDest = cell_index(s.x, s.z + 1); | |
if (base_cell(indexSrc) != base_cell(indexDest)){ | |
merge(indexSrc, indexDest); | |
maze_data[s.x][s.z + 1] |= Direction.N.getIndex(); | |
s_stack.push(new cMazeState(s)); | |
s.z += 1; s.dir = 0; | |
} | |
} | |
} | |
catch (Exception e){ | |
LogError(e); | |
return; | |
} | |
} | |
} | |
} | |
// --- get voxel data --- | |
public boolean[][][] GetMaze(int xS, int zS){ | |
int i, j; | |
int xSize = xS / MSizeX; | |
int zSize = zS / MSizeZ; | |
boolean[][][] VoxelMaze = new boolean[xS + 1][MSizeY][zS + 1]; | |
for (i = 0; i < MSizeX; i++){ | |
for (j = 0; j < MSizeZ; j++){ | |
if ((maze_data[i][j] & Direction.N.getIndex()) == 0){ | |
// draw voxel vertical line. | |
int startingPointX = xSize * i; | |
int EndingPointX = xSize * (i + 1); | |
int zPos = zSize * j; | |
for (int _x = startingPointX; _x < EndingPointX; _x++){ | |
for (int _y = 0; _y < MSizeY; _y++){ | |
VoxelMaze[_x][_y][zPos] = true; | |
} | |
} | |
} | |
if ((maze_data[i][j] & Direction.W.getIndex()) == 0){ | |
// draw voxel horizontal line. | |
int startingPointZ = zSize * j; | |
int endingPointZ = zSize * (j + 1); | |
int xPos = xSize * i; | |
for(int _y = 0; _y < MSizeY; _y++){ | |
for (int _z = startingPointZ; _z < endingPointZ; _z++){ | |
VoxelMaze[xPos][_y][_z] = true; | |
} | |
} | |
} | |
} | |
} | |
return VoxelMaze; | |
} | |
// --- Cell functions --- | |
int cell_index(int x, int y){ | |
return MSizeX * y + x; | |
} | |
int base_cell(int tIndex){ | |
int index = tIndex; | |
while(maze_base[index] >= 0){ | |
index = maze_base[index]; | |
} | |
return index; | |
} | |
void merge (int index1, int index2){ | |
int base1 = base_cell(index1); | |
int base2 = base_cell(index2); | |
maze_base[base2] = base1; | |
} | |
// --- Maze Init --- | |
void MazeInit(Random r){ | |
int i, j; | |
for (i = 0; i < MSizeX; i++){ | |
for (j = 0; j < MSizeZ; j++){ | |
maze_base[cell_index(i, j)] = -1; | |
maze_data[i][j] = 0; | |
} | |
} | |
} | |
void LogError(final Exception e){ | |
MazeGen.getInstance().getServer().getScheduler().runTask(MazeGen.getInstance(), new BukkitRunnable () { | |
@Override | |
public void run() { | |
// TODO Auto-generated method stub | |
String message = e.getClass().toString() + ": " + e.getMessage(); | |
StackTraceElement[] traceArray = e.getStackTrace(); | |
String trace = ""; | |
for (StackTraceElement element : traceArray){ | |
trace += element.toString() + "\n"; | |
} | |
MazeGen.getInstance().getServer().broadcastMessage(message + "\n" + trace); | |
}}); | |
} | |
} | |
public final class cCellPosition { | |
public int x, z; | |
public cCellPosition() {} | |
public cCellPosition(int xp, int zp) {x = xp; z = zp;} | |
} | |
public final class cMazeState { | |
public int x, z, dir; | |
public cMazeState(int tx, int tz, int td) {x = tx; z = tz; dir = td;} | |
public cMazeState(cMazeState s) {x = s.x; z = s.z; dir = s.dir;} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment