132 lines
4.2 KiB
Java
132 lines
4.2 KiB
Java
package ch.fritteli.maze.generator.model;
|
|
|
|
import io.vavr.control.Option;
|
|
import lombok.EqualsAndHashCode;
|
|
import lombok.Getter;
|
|
import lombok.NonNull;
|
|
import lombok.ToString;
|
|
|
|
@EqualsAndHashCode
|
|
@ToString
|
|
public class Maze {
|
|
|
|
private final Tile[][] field;
|
|
@Getter
|
|
private final int width;
|
|
@Getter
|
|
private final int height;
|
|
@Getter
|
|
private final long randomSeed;
|
|
@Getter
|
|
private final Position start;
|
|
@Getter
|
|
private final Position end;
|
|
|
|
public Maze(final int width, final int height) {
|
|
this(width, height, System.nanoTime());
|
|
}
|
|
|
|
public Maze(final int width, final int height, @NonNull final Position start, @NonNull final Position end) {
|
|
this(width, height, System.nanoTime(), start, end);
|
|
}
|
|
|
|
public Maze(final int width, final int height, final long randomSeed) {
|
|
this(width, height, randomSeed, new Position(0, 0), new Position(width - 1, height - 1));
|
|
}
|
|
|
|
public Maze(final int width, final int height, final long randomSeed, @NonNull final Position start, @NonNull final Position end) {
|
|
if (width <= 1 || height <= 1) {
|
|
throw new IllegalArgumentException("width and height must be >1");
|
|
}
|
|
if (start.equals(end)) {
|
|
throw new IllegalArgumentException("'start' must not be equal to 'end'");
|
|
}
|
|
if (start.getX() != 0 && start.getX() != width - 1 && start.getY() != 0 && start.getY() != height - 1) {
|
|
throw new IllegalArgumentException("'start' must be at the edge of the maze");
|
|
}
|
|
if (end.getX() != 0 && end.getX() != width - 1 && end.getY() != 0 && end.getY() != height - 1) {
|
|
throw new IllegalArgumentException("'end' must be at the edge of the maze");
|
|
}
|
|
this.width = width;
|
|
this.height = height;
|
|
this.randomSeed = randomSeed;
|
|
this.field = new Tile[width][height];
|
|
this.start = start;
|
|
this.end = end;
|
|
this.initField();
|
|
}
|
|
|
|
/**
|
|
* INTERNAL API. Exists only for deserialization. Not to be called from user code.
|
|
*/
|
|
private Maze(@NonNull final Tile[][] field, final int width, final int height, final long randomSeed) {
|
|
this.field = field;
|
|
this.width = width;
|
|
this.height = height;
|
|
this.randomSeed = randomSeed;
|
|
this.start = new Position(0, 0);
|
|
this.end = new Position(this.width - 1, this.height - 1);
|
|
}
|
|
|
|
/**
|
|
* INTERNAL API. Exists only for deserialization. Not to be called from user code.
|
|
*/
|
|
private Maze(@NonNull final Tile[][] field, final int width, final int height, @NonNull final Position start, @NonNull final Position end, final long randomSeed) {
|
|
this.field = field;
|
|
this.width = width;
|
|
this.height = height;
|
|
this.randomSeed = randomSeed;
|
|
this.start = start;
|
|
this.end = end;
|
|
}
|
|
|
|
@NonNull
|
|
public Option<Tile> getTileAt(@NonNull final Position position) {
|
|
return this.getTileAt(position.getX(), position.getY());
|
|
}
|
|
|
|
@NonNull
|
|
public Option<Tile> getTileAt(final int x, final int y) {
|
|
if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
|
|
return Option.none();
|
|
}
|
|
return Option.of(this.field[x][y]);
|
|
}
|
|
|
|
@NonNull
|
|
public Tile getStartTile() {
|
|
return this.getTileAt(this.start).get();
|
|
}
|
|
|
|
@NonNull
|
|
public Tile getEndTile() {
|
|
return this.getTileAt(this.end).get();
|
|
}
|
|
|
|
private void initField() {
|
|
for (int x = 0; x < this.width; x++) {
|
|
this.field[x] = new Tile[this.height];
|
|
for (int y = 0; y < this.height; y++) {
|
|
final Tile tile = new Tile();
|
|
this.hardenWalls(tile, x, y);
|
|
this.field[x][y] = tile;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void hardenWalls(@NonNull final Tile tile, final int x, final int y) {
|
|
if (x == 0) {
|
|
tile.preventDiggingToOrFrom(Direction.LEFT);
|
|
}
|
|
if (x == this.width - 1) {
|
|
tile.preventDiggingToOrFrom(Direction.RIGHT);
|
|
}
|
|
if (y == 0) {
|
|
tile.preventDiggingToOrFrom(Direction.TOP);
|
|
}
|
|
if (y == this.height - 1) {
|
|
tile.preventDiggingToOrFrom(Direction.BOTTOM);
|
|
}
|
|
}
|
|
}
|