All Downloads are FREE. Search and download functionalities are using the official Maven repository.

squidpony.squidgrid.mapping.DividedMazeGenerator Maven / Gradle / Ivy

Go to download

SquidLib platform-independent logic and utility code. Please refer to https://github.com/SquidPony/SquidLib .

There is a newer version: 3.0.6
Show newest version
package squidpony.squidgrid.mapping;

import squidpony.squidgrid.Direction;
import squidpony.squidmath.GWTRNG;
import squidpony.squidmath.IRNG;
import squidpony.squidmath.IntVLA;

import java.util.ArrayDeque;

/**
 * Recursively divided maze. Creates only walls and passages.
 * 

* This dungeon generator is based on a port of the rot.js version. * * @author Eben Howard - http://squidpony.com - [email protected] */ public class DividedMazeGenerator { private class DividedMazeRoom { private int left, top, right, bottom; public DividedMazeRoom(int left, int top, int right, int bottom) { this.left = left; this.top = top; this.right = right; this.bottom = bottom; } } private int width, height; private boolean[][] map; private IRNG rng; /** * Sets up the generator to make mazes the given width and height. The mazes * have a solid wall border. * * @param width * @param height */ public DividedMazeGenerator(int width, int height) { this.width = width; this.height = height; rng = new GWTRNG(); } /** * Sets up the generator to make mazes the given width and height. The mazes * have a solid wall border. * * @param width in cells * @param height in cells * @param rng the random number generator to use */ public DividedMazeGenerator(int width, int height, IRNG rng) { this.width = width; this.height = height; this.rng = rng; } /** * Builds a maze. True values represent walls. * * @return */ public boolean[][] create() { map = new boolean[width][height]; for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { map[x][y] = x == 0 || y == 0 || x + 1 == width || y + 1 == height; } } process(); return map; } private void process() { ArrayDeque stack = new ArrayDeque<>(); stack.offer(new DividedMazeRoom(1, 1, width - 2, height - 2)); while (!stack.isEmpty()) { DividedMazeRoom room = stack.removeFirst(); IntVLA availX = new IntVLA(), availY = new IntVLA(); for (int x = room.left + 1; x < room.right; x++) { boolean top = map[x][room.top - 1]; boolean bottom = map[x][room.bottom + 1]; if (top && bottom && (x & 1) == 0) { availX.add(x); } } for (int y = room.top + 1; y < room.bottom; y++) { boolean left = map[room.left - 1][y]; boolean right = map[room.right + 1][y]; if (left && right && (y & 1) == 0) { availY.add(y); } } if (availX.isEmpty() || availY.isEmpty()) { continue; } int x2 = availX.getRandomElement(rng); int y2 = availY.getRandomElement(rng); map[x2][y2] = true; for (Direction dir : Direction.CARDINALS) { switch (dir) { case LEFT: for (int x = room.left; x < x2; x++) { map[x][y2] = true; } break; case RIGHT: for (int x = x2 + 1; x <= room.right; x++) { map[x][y2] = true; } break; case UP: for (int y = room.top; y < y2; y++) { map[x2][y] = true; } break; case DOWN: for (int y = y2 + 1; y <= room.bottom; y++) { map[x2][y] = true; } break; case NONE: break; case DOWN_LEFT: case DOWN_RIGHT: case UP_LEFT: case UP_RIGHT: throw new IllegalStateException("There should only be cardinal directions here"); } } //// the commented code below actually works fine, but it's a little wasteful on RAM // ArrayList dirs = Maker.makeList(Direction.CARDINALS); // dirs.remove(rng.getRandomElement(dirs)); //// not sure if the order being random matters, but this will remove a random item Direction[] dirs = rng.randomPortion(Direction.CARDINALS, new Direction[3]); for (Direction dir : dirs) { switch (dir) { case LEFT: map[rng.between(room.left, x2)][y2] = false; break; case RIGHT: map[rng.between(x2 + 1, room.right + 1)][y2] = false; break; case UP: map[x2][rng.between(room.top, y2)] = false; break; case DOWN: map[x2][rng.between(y2 + 1, room.bottom + 1)] = false; break; case NONE: break; case DOWN_LEFT: case DOWN_RIGHT: case UP_LEFT: case UP_RIGHT: throw new IllegalStateException("There should only be cardinal directions here"); } } stack.offer(new DividedMazeRoom(room.left, room.top, x2 - 1, y2 - 1)); stack.offer(new DividedMazeRoom(x2 + 1, room.top, room.right, y2 - 1)); stack.offer(new DividedMazeRoom(room.left, y2 + 1, x2 - 1, room.bottom)); stack.offer(new DividedMazeRoom(x2 + 1, y2 + 1, room.right, room.bottom)); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy