Skip to content

Commit

Permalink
Deprecated Maze Generation
Browse files Browse the repository at this point in the history
  • Loading branch information
LudoCrypt committed May 13, 2022
1 parent 352f14b commit bb18326
Show file tree
Hide file tree
Showing 4 changed files with 329 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package net.ludocrypt.limlib.api.world.maze.deprecated;

import java.util.List;
import java.util.Random;
import java.util.Stack;

import com.google.common.collect.Lists;

@Deprecated
public class DepthFirstMaze extends MazeComponent {

public Stack<Vec2i> stack = new Stack<Vec2i>();

public Random random;

public DepthFirstMaze(int width, int height, Random random) {
super(width, height);
this.random = random;
}

@Override
public void generateMaze() {
this.maze[0].visited();
this.stack.push(new Vec2i(0, 0));
while (visitedCells < this.width * this.height) {
List<Integer> neighbours = Lists.newArrayList();

// North Neighbour
if (this.hasNorthNeighbor(this.stack.peek())) {
neighbours.add(0);
}

// East Neighbour
if (this.hasEastNeighbor(this.stack.peek())) {
neighbours.add(1);
}

// South Neighbour
if (this.hasSouthNeighbor(this.stack.peek())) {
neighbours.add(2);
}

// West Neighbour
if (this.hasWestNeighbor(this.stack.peek())) {
neighbours.add(3);
}

// Neighbour check
if (!neighbours.isEmpty()) {
int nextCellDir = neighbours.get(random.nextInt(neighbours.size()));

switch (nextCellDir) {
case 0: // North
this.cellState(this.stack.peek().getX(), this.stack.peek().getY()).north();
this.cellState(this.stack.peek().getX() + 1, this.stack.peek().getY()).south();
this.cellState(this.stack.peek().getX() + 1, this.stack.peek().getY()).visited();
this.stack.push(new Vec2i(this.stack.peek().getX() + 1, this.stack.peek().getY()));
break;
case 1: // East
this.cellState(this.stack.peek().getX(), this.stack.peek().getY()).east();
this.cellState(this.stack.peek().getX(), this.stack.peek().getY() + 1).west();
this.cellState(this.stack.peek().getX(), this.stack.peek().getY() + 1).visited();
this.stack.push(new Vec2i(this.stack.peek().getX(), this.stack.peek().getY() + 1));
break;
case 2: // South
this.cellState(this.stack.peek().getX(), this.stack.peek().getY()).south();
this.cellState(this.stack.peek().getX() - 1, this.stack.peek().getY()).north();
this.cellState(this.stack.peek().getX() - 1, this.stack.peek().getY()).visited();
this.stack.push(new Vec2i(this.stack.peek().getX() - 1, this.stack.peek().getY()));
break;
case 3: // West
this.cellState(this.stack.peek().getX(), this.stack.peek().getY()).west();
this.cellState(this.stack.peek().getX(), this.stack.peek().getY() - 1).east();
this.cellState(this.stack.peek().getX(), this.stack.peek().getY() - 1).visited();
this.stack.push(new Vec2i(this.stack.peek().getX(), this.stack.peek().getY() - 1));
break;
}

// Visit Cell
this.visitedCells++;

} else {
// Backtrack
this.stack.pop();
}
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
package net.ludocrypt.limlib.api.world.maze.deprecated;

@Deprecated
public abstract class MazeComponent {

public final int width;
public final int height;

public final CellState[] maze;

public int visitedCells = 0;

public MazeComponent(int width, int height) {
this.width = width;
this.height = height;
this.maze = new CellState[width * height];
for (int i = 0; i < width * height; i++) {
this.maze[i] = new CellState();
}
this.visitedCells = 1;
}

public abstract void generateMaze();

public CellState cellState(int x, int y) {
return this.maze[y * this.width + x];
}

public boolean hasNorthNeighbor(Vec2i vec) {
return (vec.getX() + 1 < this.height) && !(this.maze[((vec.getY()) * this.width + (vec.getX() + 1))].isVisited());
}

public boolean hasEastNeighbor(Vec2i vec) {
return (vec.getY() + 1 < this.width) && !(this.maze[((vec.getY() + 1) * this.width + (vec.getX()))].isVisited());
}

public boolean hasSouthNeighbor(Vec2i vec) {
return (vec.getX() > 0) && !(this.maze[((vec.getY()) * this.width + (vec.getX() - 1))].isVisited());
}

public boolean hasWestNeighbor(Vec2i vec) {
return (vec.getY() > 0) && !(this.maze[((vec.getY() - 1) * this.width + (vec.getX()))].isVisited());
}

public boolean hasNeighbors(Vec2i vec) {
return this.hasNorthNeighbor(vec) || this.hasEastNeighbor(vec) || this.hasSouthNeighbor(vec) || this.hasWestNeighbor(vec);
}

public static class CellState {

private boolean north = false;
private boolean east = false;
private boolean south = false;
private boolean west = false;
private boolean visited = false;

public void north() {
this.north = true;
}

public void east() {
this.east = true;
}

public void south() {
this.south = true;
}

public void west() {
this.west = true;
}

public void visited() {
this.visited = true;
}

public void setNorth(boolean north) {
this.north = north;
}

public void setEast(boolean east) {
this.east = east;
}

public void setSouth(boolean south) {
this.south = south;
}

public void setWest(boolean west) {
this.west = west;
}

public void setVisited(boolean visited) {
this.visited = visited;
}

public boolean isNorth() {
return north;
}

public boolean isEast() {
return east;
}

public boolean isSouth() {
return south;
}

public boolean isWest() {
return west;
}

public boolean isVisited() {
return visited;
}

}

public static class Vec2i {

private int x;
private int y;

public Vec2i(int x, int y) {
this.x = x;
this.y = y;
}

public int getX() {
return x;
}

public int getY() {
return y;
}

@Override
public String toString() {
return "(" + this.x + ", " + this.y + ")";
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package net.ludocrypt.limlib.api.world.maze.deprecated;

import java.util.HashMap;
import java.util.Random;
import java.util.function.Function;

import com.mojang.serialization.Codec;

import net.ludocrypt.limlib.api.world.maze.deprecated.MazeComponent.CellState;
import net.ludocrypt.limlib.impl.LimlibRegistries;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.ChunkRegion;
import net.minecraft.world.chunk.Chunk;

@Deprecated
public abstract class MazeGenerator {

public static final Codec<MazeGenerator> CODEC = LimlibRegistries.LIMINAL_MAZE_GENERATOR.getCodec().dispatchStable(MazeGenerator::getCodec, Function.identity());

private final HashMap<BlockPos, MazeComponent> mazes = new HashMap<BlockPos, MazeComponent>(30);

public final int width;
public final int height;
public final int thickness;
public final boolean redundancy;
public final long seedModifier;

public MazeGenerator(int width, int height, int thickness, boolean redundancy, long seedModifier) {
this.width = width;
this.height = height;
this.thickness = thickness;
this.redundancy = redundancy;
this.seedModifier = seedModifier;
}

public void generateMaze(BlockPos pos, Chunk chunk, ChunkRegion region) {
if (thickness < 1)
throw new UnsupportedOperationException("Thickness can not be less than 1");

for (int x = 0; x < 16; x++) {
for (int y = 0; y < 16; y++) {
BlockPos inPos = pos.add(x, 0, y);
if (mod(inPos.getX(), thickness) == 0 && mod(inPos.getZ(), thickness) == 0) {
BlockPos mazePos = new BlockPos(inPos.getX() - mod(inPos.getX(), (width * thickness * 2)), 0, inPos.getZ() - mod(inPos.getZ(), (height * thickness * 2)));

MazeComponent maze;
if (this.mazes.containsKey(mazePos)) {
maze = this.mazes.get(mazePos);
} else {
maze = this.newMaze(region, chunk, redundancy ? width + 4 : width, redundancy ? height + 4 : height, new Random(blockSeed(mazePos.getX(), mazePos.getZ(), seedModifier)));
this.mazes.put(mazePos, maze);
}

BlockPos originPos = new BlockPos(inPos.getX() - mod(inPos.getX(), (2 * thickness)), 0, inPos.getZ() - mod(inPos.getZ(), (2 * thickness)));

boolean isOpenCell = mod(inPos.getX(), (2 * thickness)) == 0 && mod(inPos.getZ(), (2 * thickness)) == 0;
boolean isWallCell = mod(inPos.getX(), (2 * thickness)) == thickness && mod(inPos.getZ(), (2 * thickness)) == thickness;
boolean isTopCell = mod(inPos.getX(), (2 * thickness)) == thickness && mod(inPos.getZ(), (2 * thickness)) == 0;
boolean isSideCell = mod(inPos.getX(), (2 * thickness)) == 0 && mod(inPos.getZ(), (2 * thickness)) == thickness;

int mazeX = mod(originPos.getX(), (width * thickness * 2)) / (2 * thickness);
int mazeY = mod(originPos.getZ(), (height * thickness * 2)) / (2 * thickness);

CellState originCell = maze.cellState(redundancy ? mazeX + 2 : mazeX, redundancy ? mazeY + 2 : mazeX);

this.decorateCell(inPos, originPos, chunk, region, originCell, isOpenCell, isWallCell, isTopCell, isSideCell, thickness);
}
}
}
}

public abstract MazeComponent newMaze(ChunkRegion region, Chunk chunk, int width, int height, Random random);

public abstract void decorateCell(BlockPos pos, BlockPos origin, Chunk chunk, ChunkRegion region, CellState state, boolean isOpen, boolean isWall, boolean isTopCell, boolean isSideCell, int thickness);

public abstract Codec<? extends MazeGenerator> getCodec();

protected int mod(int x, int n) {
int r = x % n;
if (r < 0) {
r += n;
}
return r;
}

protected long blockSeed(long x, long y, long z) {
long l = (x * 3129871) ^ z * 116129781L ^ y;
l = l * l * 42317861L + l * 11L;
return l >> 16;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
import net.ludocrypt.limlib.api.render.LiminalBaseEffects;
import net.ludocrypt.limlib.api.render.LiminalShaderApplier;
import net.ludocrypt.limlib.api.render.LiminalSkyRenderer;
import net.ludocrypt.limlib.api.world.maze.deprecated.MazeGenerator;
import net.minecraft.util.Identifier;
import net.minecraft.util.registry.SimpleRegistry;

@SuppressWarnings("unchecked")
@SuppressWarnings({ "unchecked", "deprecation" })
public class LimlibRegistries {

public static final SimpleRegistry<LiminalWorld> LIMINAL_WORLD = FabricRegistryBuilder.createSimple(LiminalWorld.class, new Identifier("limlib", "limlib_world")).attribute(RegistryAttribute.SYNCED).buildAndRegister();
Expand All @@ -20,4 +21,6 @@ public class LimlibRegistries {
public static final SimpleRegistry<Codec<? extends LiminalShaderApplier>> LIMINAL_SHADER_APPLIER = (SimpleRegistry<Codec<? extends LiminalShaderApplier>>) (Object) FabricRegistryBuilder.createSimple(Codec.class, new Identifier("limlib", "limlib_shader_applier")).attribute(RegistryAttribute.SYNCED).buildAndRegister();
public static final SimpleRegistry<Codec<? extends LiminalBaseEffects>> LIMINAL_BASE_EFFECTS = (SimpleRegistry<Codec<? extends LiminalBaseEffects>>) (Object) FabricRegistryBuilder.createSimple(Codec.class, new Identifier("limlib", "limlib_base_effects")).attribute(RegistryAttribute.SYNCED).buildAndRegister();

public static final SimpleRegistry<Codec<? extends MazeGenerator>> LIMINAL_MAZE_GENERATOR = (SimpleRegistry<Codec<? extends MazeGenerator>>) (Object) FabricRegistryBuilder.createSimple(Codec.class, new Identifier("limlib", "limlib_maze_generator")).attribute(RegistryAttribute.SYNCED).buildAndRegister();

}

0 comments on commit bb18326

Please sign in to comment.