Updating tons of dependencies.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
f1171328a9
commit
ae7dfe7c3c
41 changed files with 285 additions and 283 deletions
24
pom.xml
24
pom.xml
|
|
@ -1,11 +1,12 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>ch.fritteli</groupId>
|
<groupId>ch.fritteli</groupId>
|
||||||
<artifactId>fritteli-build-parent</artifactId>
|
<artifactId>fritteli-build-parent</artifactId>
|
||||||
<version>5.1.0</version>
|
<version>6.1.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>ch.fritteli.a-maze-r</groupId>
|
<groupId>ch.fritteli.a-maze-r</groupId>
|
||||||
|
|
@ -55,10 +56,10 @@
|
||||||
</distributionManagement>
|
</distributionManagement>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<jackson.version>2.17.1</jackson.version>
|
<guava.version>33.5.0-jre</guava.version>
|
||||||
<jsonschema2pojo-maven-plugin.version>1.2.1</jsonschema2pojo-maven-plugin.version>
|
<jsonschema2pojo-maven-plugin.version>1.2.2</jsonschema2pojo-maven-plugin.version>
|
||||||
<maven-site-plugin.version>4.0.0-M8</maven-site-plugin.version>
|
<maven-site-plugin.version>4.0.0-M16</maven-site-plugin.version>
|
||||||
<pdfbox.version>3.0.2</pdfbox.version>
|
<pdfbox.version>3.0.6</pdfbox.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
@ -67,8 +68,8 @@
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.jetbrains</groupId>
|
<groupId>org.jspecify</groupId>
|
||||||
<artifactId>annotations</artifactId>
|
<artifactId>jspecify</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.vavr</groupId>
|
<groupId>io.vavr</groupId>
|
||||||
|
|
@ -77,7 +78,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.guava</groupId>
|
<groupId>com.google.guava</groupId>
|
||||||
<artifactId>guava</artifactId>
|
<artifactId>guava</artifactId>
|
||||||
<version>33.2.1-jre</version>
|
<version>${guava.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.apache.pdfbox</groupId>
|
<groupId>org.apache.pdfbox</groupId>
|
||||||
|
|
@ -87,12 +88,10 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
<artifactId>jackson-annotations</artifactId>
|
<artifactId>jackson-annotations</artifactId>
|
||||||
<version>${jackson.version}</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<groupId>tools.jackson.core</groupId>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<artifactId>jackson-databind</artifactId>
|
||||||
<version>${jackson.version}</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
|
|
@ -109,7 +108,6 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
<artifactId>assertj-core</artifactId>
|
<artifactId>assertj-core</artifactId>
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import ch.fritteli.maze.generator.renderer.text.TextRenderer;
|
||||||
import ch.fritteli.maze.generator.renderer.textfile.TextFileRenderer;
|
import ch.fritteli.maze.generator.renderer.textfile.TextFileRenderer;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
|
|
@ -20,7 +20,7 @@ import java.nio.file.Paths;
|
||||||
@UtilityClass
|
@UtilityClass
|
||||||
public class Main {
|
public class Main {
|
||||||
|
|
||||||
public static void main(@NotNull final String[] args) {
|
static void main(@NonNull final String[] args) {
|
||||||
final int width = 20;
|
final int width = 20;
|
||||||
final int height = 30;
|
final int height = 30;
|
||||||
final Maze maze = new Maze(width, height/*, 0*/);
|
final Maze maze = new Maze(width, height/*, 0*/);
|
||||||
|
|
@ -59,7 +59,7 @@ public class Main {
|
||||||
log.info("PDF rendering to file:\n{}", pdfFileRenderer.render(maze));
|
log.info("PDF rendering to file:\n{}", pdfFileRenderer.render(maze));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getBaseFilename(@NotNull final Maze maze) {
|
private static String getBaseFilename(@NonNull final Maze maze) {
|
||||||
return "maze-" + maze.getWidth() + "x" + maze.getHeight() + "-" + maze.getRandomSeed();
|
return "maze-" + maze.getWidth() + "x" + maze.getHeight() + "-" + maze.getRandomSeedStringRepresentation();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,18 +1,18 @@
|
||||||
package ch.fritteli.maze.generator.algorithm;
|
package ch.fritteli.maze.generator.algorithm;
|
||||||
|
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public abstract class AbstractMazeGeneratorAlgorithm implements MazeGeneratorAlgorithm {
|
public abstract class AbstractMazeGeneratorAlgorithm implements MazeGeneratorAlgorithm {
|
||||||
@NotNull
|
@NonNull
|
||||||
protected final Maze maze;
|
protected final Maze maze;
|
||||||
@NotNull
|
@NonNull
|
||||||
protected final Random random;
|
protected final Random random;
|
||||||
|
|
||||||
|
|
||||||
protected AbstractMazeGeneratorAlgorithm(@NotNull final Maze maze, @NotNull final String algorithmName) {
|
protected AbstractMazeGeneratorAlgorithm(@NonNull final Maze maze, @NonNull final String algorithmName) {
|
||||||
this.maze = maze;
|
this.maze = maze;
|
||||||
this.random = new Random(maze.getRandomSeed());
|
this.random = new Random(maze.getRandomSeed());
|
||||||
this.maze.setAlgorithm(algorithmName);
|
this.maze.setAlgorithm(algorithmName);
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,17 @@ import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.model.Position;
|
import ch.fritteli.maze.generator.model.Position;
|
||||||
import ch.fritteli.maze.generator.model.Tile;
|
import ch.fritteli.maze.generator.model.Tile;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
public class RandomDepthFirst extends AbstractMazeGeneratorAlgorithm {
|
public class RandomDepthFirst extends AbstractMazeGeneratorAlgorithm {
|
||||||
@NotNull
|
@NonNull
|
||||||
private final Deque<Position> positions = new LinkedList<>();
|
private final Deque<Position> positions = new LinkedList<>();
|
||||||
|
|
||||||
public RandomDepthFirst(@NotNull final Maze maze) {
|
public RandomDepthFirst(@NonNull final Maze maze) {
|
||||||
super(maze, "Random Depth First");
|
super(maze, "Random Depth First");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -79,7 +79,7 @@ public class RandomDepthFirst extends AbstractMazeGeneratorAlgorithm {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Direction determineDirectionForDigging(@NotNull final Position position) {
|
private Direction determineDirectionForDigging(@NonNull final Position position) {
|
||||||
if (position.y() == 0) {
|
if (position.y() == 0) {
|
||||||
return Direction.TOP;
|
return Direction.TOP;
|
||||||
}
|
}
|
||||||
|
|
@ -95,12 +95,12 @@ public class RandomDepthFirst extends AbstractMazeGeneratorAlgorithm {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void digFrom(@NotNull final Tile tile, @NotNull final Direction direction) {
|
private void digFrom(@NonNull final Tile tile, @NonNull final Direction direction) {
|
||||||
tile.enableDiggingToOrFrom(direction);
|
tile.enableDiggingToOrFrom(direction);
|
||||||
tile.digFrom(direction);
|
tile.digFrom(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void digTo(@NotNull final Tile tile, @NotNull final Direction direction) {
|
private void digTo(@NonNull final Tile tile, @NonNull final Direction direction) {
|
||||||
tile.enableDiggingToOrFrom(direction);
|
tile.enableDiggingToOrFrom(direction);
|
||||||
tile.digTo(direction);
|
tile.digTo(direction);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package ch.fritteli.maze.generator.algorithm.wilson;
|
||||||
import ch.fritteli.maze.generator.model.Direction;
|
import ch.fritteli.maze.generator.model.Direction;
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.model.Position;
|
import ch.fritteli.maze.generator.model.Position;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
@ -12,10 +12,10 @@ import java.util.Stack;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class MazeSolver {
|
public class MazeSolver {
|
||||||
@NotNull
|
@NonNull
|
||||||
private final Maze maze;
|
private final Maze maze;
|
||||||
|
|
||||||
MazeSolver(@NotNull final Maze maze) {
|
MazeSolver(@NonNull final Maze maze) {
|
||||||
this.maze = maze;
|
this.maze = maze;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,10 +32,10 @@ public class MazeSolver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<Position> getSolution(@NotNull Position position,
|
private List<Position> getSolution(@NonNull Position position,
|
||||||
@NotNull Direction forbidden) {
|
@NonNull Direction forbidden) {
|
||||||
record PathElement(@NotNull Position position,
|
record PathElement(@NonNull Position position,
|
||||||
@NotNull EnumSet<Direction> possibleDirections) {
|
@NonNull EnumSet<Direction> possibleDirections) {
|
||||||
}
|
}
|
||||||
final Stack<PathElement> solution = new Stack<>();
|
final Stack<PathElement> solution = new Stack<>();
|
||||||
final EnumSet<Direction> directions = this.maze.getTileAt(position).get().getOpenDirections();
|
final EnumSet<Direction> directions = this.maze.getTileAt(position).get().getOpenDirections();
|
||||||
|
|
|
||||||
|
|
@ -6,24 +6,24 @@ import io.vavr.collection.List;
|
||||||
import io.vavr.collection.Stream;
|
import io.vavr.collection.Stream;
|
||||||
import io.vavr.collection.Traversable;
|
import io.vavr.collection.Traversable;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
class Path {
|
class Path {
|
||||||
private final int width;
|
private final int width;
|
||||||
private final int height;
|
private final int height;
|
||||||
@NotNull
|
@NonNull
|
||||||
private List<Position> positions;
|
private List<Position> positions;
|
||||||
|
|
||||||
Path(@NotNull final Position start, int width, int height) {
|
Path(@NonNull final Position start, int width, int height) {
|
||||||
this.positions = List.of(start);
|
this.positions = List.of(start);
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
Position growRandom(@NotNull final Random random) {
|
Position growRandom(@NonNull final Random random) {
|
||||||
final Position position = this.nextRandomPosition(random);
|
final Position position = this.nextRandomPosition(random);
|
||||||
if (this.contains(position)) {
|
if (this.contains(position)) {
|
||||||
this.removeLoopUpTo(position);
|
this.removeLoopUpTo(position);
|
||||||
|
|
@ -33,17 +33,17 @@ class Path {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
List<Position> getPositions() {
|
List<Position> getPositions() {
|
||||||
return this.positions;
|
return this.positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
Position getStart() {
|
Position getStart() {
|
||||||
return this.positions.last();
|
return this.positions.last();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
Traversable<Direction> getMovesFromStart() {
|
Traversable<Direction> getMovesFromStart() {
|
||||||
return this.positions.reverse().sliding(2)
|
return this.positions.reverse().sliding(2)
|
||||||
.flatMap(positions1 -> Option.when(
|
.flatMap(positions1 -> Option.when(
|
||||||
|
|
@ -54,8 +54,8 @@ class Path {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private Position nextRandomPosition(@NotNull final Random random) {
|
private Position nextRandomPosition(@NonNull final Random random) {
|
||||||
final Direction randomDirection = this.getRandomDirection(random);
|
final Direction randomDirection = this.getRandomDirection(random);
|
||||||
final Position nextPosition = this.positions.head().move(randomDirection);
|
final Position nextPosition = this.positions.head().move(randomDirection);
|
||||||
if (this.isWithinBounds(nextPosition) && !nextPosition.equals(this.positions.head())) {
|
if (this.isWithinBounds(nextPosition) && !nextPosition.equals(this.positions.head())) {
|
||||||
|
|
@ -64,20 +64,20 @@ class Path {
|
||||||
return this.nextRandomPosition(random);
|
return this.nextRandomPosition(random);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isWithinBounds(@NotNull final Position position) {
|
private boolean isWithinBounds(@NonNull final Position position) {
|
||||||
return position.x() >= 0 && position.x() < this.width && position.y() >= 0 && position.y() < this.height;
|
return position.x() >= 0 && position.x() < this.width && position.y() >= 0 && position.y() < this.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean contains(@NotNull final Position position) {
|
private boolean contains(@NonNull final Position position) {
|
||||||
return this.positions.contains(position);
|
return this.positions.contains(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeLoopUpTo(@NotNull final Position position) {
|
private void removeLoopUpTo(@NonNull final Position position) {
|
||||||
this.positions = this.positions.dropUntil(position::equals);
|
this.positions = this.positions.dropUntil(position::equals);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private Direction getRandomDirection(@NotNull final Random random) {
|
private Direction getRandomDirection(@NonNull final Random random) {
|
||||||
final Direction[] array = Direction.values();
|
final Direction[] array = Direction.values();
|
||||||
return array[random.nextInt(array.length)];
|
return array[random.nextInt(array.length)];
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import io.vavr.Tuple;
|
||||||
import io.vavr.collection.Stream;
|
import io.vavr.collection.Stream;
|
||||||
import io.vavr.collection.Traversable;
|
import io.vavr.collection.Traversable;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
|
@ -18,13 +18,13 @@ import java.util.Random;
|
||||||
class PathsBuilder {
|
class PathsBuilder {
|
||||||
private final int width;
|
private final int width;
|
||||||
private final int height;
|
private final int height;
|
||||||
@NotNull
|
@NonNull
|
||||||
private final Random random;
|
private final Random random;
|
||||||
@NotNull
|
@NonNull
|
||||||
private final Multimap<Integer, Integer> availablePositions;
|
private final Multimap<Integer, Integer> availablePositions;
|
||||||
|
|
||||||
PathsBuilder(@NotNull final Maze maze,
|
PathsBuilder(@NonNull final Maze maze,
|
||||||
@NotNull final Random random) {
|
@NonNull final Random random) {
|
||||||
this.width = maze.getWidth();
|
this.width = maze.getWidth();
|
||||||
this.height = maze.getHeight();
|
this.height = maze.getHeight();
|
||||||
this.random = random;
|
this.random = random;
|
||||||
|
|
@ -44,7 +44,7 @@ class PathsBuilder {
|
||||||
*
|
*
|
||||||
* @return A {@link Traversable} of generated {@link Path Paths}.
|
* @return A {@link Traversable} of generated {@link Path Paths}.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
Traversable<Path> buildPaths() {
|
Traversable<Path> buildPaths() {
|
||||||
this.initializeWithRandomStartingPosition();
|
this.initializeWithRandomStartingPosition();
|
||||||
|
|
||||||
|
|
@ -68,13 +68,13 @@ class PathsBuilder {
|
||||||
*
|
*
|
||||||
* @return An {@link Option} of a new {@link Path} instance.
|
* @return An {@link Option} of a new {@link Path} instance.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
private Option<Path> buildPath() {
|
private Option<Path> buildPath() {
|
||||||
return this.initializeNewPath()
|
return this.initializeNewPath()
|
||||||
.map(this::growPath);
|
.map(this::growPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private Option<Path> initializeNewPath() {
|
private Option<Path> initializeNewPath() {
|
||||||
return this.popRandomPosition()
|
return this.popRandomPosition()
|
||||||
.map(position -> new Path(position, this.width, this.height));
|
.map(position -> new Path(position, this.width, this.height));
|
||||||
|
|
@ -87,8 +87,8 @@ class PathsBuilder {
|
||||||
* @param path The {@link Path} to grow.
|
* @param path The {@link Path} to grow.
|
||||||
* @return The final {@link Path} that reaches the maze.
|
* @return The final {@link Path} that reaches the maze.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
private Path growPath(@NotNull final Path path) {
|
private Path growPath(@NonNull final Path path) {
|
||||||
Position lastPosition;
|
Position lastPosition;
|
||||||
do {
|
do {
|
||||||
lastPosition = path.growRandom(this.random);
|
lastPosition = path.growRandom(this.random);
|
||||||
|
|
@ -96,15 +96,15 @@ class PathsBuilder {
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isNotPartOfMaze(@NotNull final Position position) {
|
private boolean isNotPartOfMaze(@NonNull final Position position) {
|
||||||
return this.availablePositions.containsEntry(position.x(), position.y());
|
return this.availablePositions.containsEntry(position.x(), position.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPartOfMaze(@NotNull final Position position) {
|
private void setPartOfMaze(@NonNull final Position position) {
|
||||||
this.availablePositions.remove(position.x(), position.y());
|
this.availablePositions.remove(position.x(), position.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setPartOfMaze(@NotNull final Path path) {
|
private void setPartOfMaze(@NonNull final Path path) {
|
||||||
path.getPositions().forEach(this::setPartOfMaze);
|
path.getPositions().forEach(this::setPartOfMaze);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +114,7 @@ class PathsBuilder {
|
||||||
*
|
*
|
||||||
* @return An available position or {@link io.vavr.control.Option.None}.
|
* @return An available position or {@link io.vavr.control.Option.None}.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
private Option<Position> popRandomPosition() {
|
private Option<Position> popRandomPosition() {
|
||||||
if (this.availablePositions.isEmpty()) {
|
if (this.availablePositions.isEmpty()) {
|
||||||
return Option.none();
|
return Option.none();
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@ import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.model.Position;
|
import ch.fritteli.maze.generator.model.Position;
|
||||||
import ch.fritteli.maze.generator.model.Tile;
|
import ch.fritteli.maze.generator.model.Tile;
|
||||||
import io.vavr.collection.Traversable;
|
import io.vavr.collection.Traversable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of <a href="https://en.wikipedia.org/wiki/Maze_generation_algorithm#Wilson's_algorithm">Wilson's Algorithm</a>.
|
* An implementation of <a href="https://en.wikipedia.org/wiki/Maze_generation_algorithm#Wilson's_algorithm">Wilson's Algorithm</a>.
|
||||||
|
|
@ -29,12 +29,12 @@ import org.jetbrains.annotations.Nullable;
|
||||||
*/
|
*/
|
||||||
public class Wilson extends AbstractMazeGeneratorAlgorithm {
|
public class Wilson extends AbstractMazeGeneratorAlgorithm {
|
||||||
|
|
||||||
public Wilson(@NotNull final Maze maze) {
|
public Wilson(@NonNull final Maze maze) {
|
||||||
super(maze, "Wilson");
|
super(maze, "Wilson");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
static Direction getDirectionToOuterWall(@NotNull final Position position,
|
static Direction getDirectionToOuterWall(@NonNull final Position position,
|
||||||
final int width,
|
final int width,
|
||||||
final int height) {
|
final int height) {
|
||||||
if (position.y() == 0) {
|
if (position.y() == 0) {
|
||||||
|
|
@ -60,7 +60,7 @@ public class Wilson extends AbstractMazeGeneratorAlgorithm {
|
||||||
this.applyPathsToMaze(paths);
|
this.applyPathsToMaze(paths);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyPathsToMaze(@NotNull final Traversable<Path> paths) {
|
private void applyPathsToMaze(@NonNull final Traversable<Path> paths) {
|
||||||
this.openStartAndEndWalls();
|
this.openStartAndEndWalls();
|
||||||
paths.forEach(path -> path.getMovesFromStart()
|
paths.forEach(path -> path.getMovesFromStart()
|
||||||
.foldLeft(
|
.foldLeft(
|
||||||
|
|
@ -83,14 +83,14 @@ public class Wilson extends AbstractMazeGeneratorAlgorithm {
|
||||||
this.openWall(this.maze.getEnd(), this.maze.getEndTile());
|
this.openWall(this.maze.getEnd(), this.maze.getEndTile());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openWall(@NotNull final Position position, @NotNull final Tile tile) {
|
private void openWall(@NonNull final Position position, @NonNull final Tile tile) {
|
||||||
final Direction direction = this.getDirectionToOuterWall(position);
|
final Direction direction = this.getDirectionToOuterWall(position);
|
||||||
tile.enableDiggingToOrFrom(direction);
|
tile.enableDiggingToOrFrom(direction);
|
||||||
tile.digTo(direction);
|
tile.digTo(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Direction getDirectionToOuterWall(@NotNull final Position position) {
|
private Direction getDirectionToOuterWall(@NonNull final Position position) {
|
||||||
return getDirectionToOuterWall(position, this.maze.getWidth(), this.maze.getHeight());
|
return getDirectionToOuterWall(position, this.maze.getWidth(), this.maze.getHeight());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package ch.fritteli.maze.generator.model;
|
package ch.fritteli.maze.generator.model;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
public enum Direction {
|
public enum Direction {
|
||||||
TOP,
|
TOP,
|
||||||
|
|
@ -8,7 +8,7 @@ public enum Direction {
|
||||||
BOTTOM,
|
BOTTOM,
|
||||||
LEFT;
|
LEFT;
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public Direction invert() {
|
public Direction invert() {
|
||||||
return switch (this) {
|
return switch (this) {
|
||||||
case TOP -> BOTTOM;
|
case TOP -> BOTTOM;
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
@EqualsAndHashCode
|
@EqualsAndHashCode
|
||||||
@ToString
|
@ToString
|
||||||
|
|
@ -30,7 +30,7 @@ public class Maze {
|
||||||
this(width, height, System.nanoTime());
|
this(width, height, System.nanoTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Maze(final int width, final int height, @NotNull final Position start, @NotNull final Position end) {
|
public Maze(final int width, final int height, @NonNull final Position start, @NonNull final Position end) {
|
||||||
this(width, height, System.nanoTime(), start, end);
|
this(width, height, System.nanoTime(), start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -41,8 +41,8 @@ public class Maze {
|
||||||
public Maze(final int width,
|
public Maze(final int width,
|
||||||
final int height,
|
final int height,
|
||||||
final long randomSeed,
|
final long randomSeed,
|
||||||
@NotNull final Position start,
|
@NonNull final Position start,
|
||||||
@NotNull final Position end) {
|
@NonNull final Position end) {
|
||||||
if (width <= 1 || height <= 1) {
|
if (width <= 1 || height <= 1) {
|
||||||
throw new IllegalArgumentException("width and height must be >1");
|
throw new IllegalArgumentException("width and height must be >1");
|
||||||
}
|
}
|
||||||
|
|
@ -67,7 +67,7 @@ public class Maze {
|
||||||
/**
|
/**
|
||||||
* INTERNAL API. Exists only for deserialization. Not to be called from user code.
|
* INTERNAL API. Exists only for deserialization. Not to be called from user code.
|
||||||
*/
|
*/
|
||||||
private Maze(@NotNull final Tile[][] field, final int width, final int height, final long randomSeed) {
|
private Maze(@NonNull final Tile[][] field, final int width, final int height, final long randomSeed) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
|
@ -79,11 +79,11 @@ public class Maze {
|
||||||
/**
|
/**
|
||||||
* INTERNAL API. Exists only for deserialization. Not to be called from user code.
|
* INTERNAL API. Exists only for deserialization. Not to be called from user code.
|
||||||
*/
|
*/
|
||||||
private Maze(@NotNull final Tile[][] field,
|
private Maze(@NonNull final Tile[][] field,
|
||||||
final int width,
|
final int width,
|
||||||
final int height,
|
final int height,
|
||||||
@NotNull final Position start,
|
@NonNull final Position start,
|
||||||
@NotNull final Position end,
|
@NonNull final Position end,
|
||||||
final long randomSeed) {
|
final long randomSeed) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
|
|
@ -96,13 +96,13 @@ public class Maze {
|
||||||
/**
|
/**
|
||||||
* INTERNAL API. Exists only for deserialization. Not to be called from user code.
|
* INTERNAL API. Exists only for deserialization. Not to be called from user code.
|
||||||
*/
|
*/
|
||||||
private Maze(@NotNull final Tile[][] field,
|
private Maze(@NonNull final Tile[][] field,
|
||||||
final int width,
|
final int width,
|
||||||
final int height,
|
final int height,
|
||||||
@NotNull final Position start,
|
@NonNull final Position start,
|
||||||
@NotNull final Position end,
|
@NonNull final Position end,
|
||||||
final long randomSeed,
|
final long randomSeed,
|
||||||
@NotNull final String algorithm) {
|
@NonNull final String algorithm) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
|
|
@ -112,29 +112,34 @@ public class Maze {
|
||||||
this.end = end;
|
this.end = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public Option<Tile> getTileAt(@NotNull final Position position) {
|
public Option<Tile> getTileAt(@NonNull final Position position) {
|
||||||
return this.getTileAt(position.x(), position.y());
|
return this.getTileAt(position.x(), position.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public Option<Tile> getTileAt(final int x, final int y) {
|
public Option<Tile> getTileAt(final int x, final int y) {
|
||||||
if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
|
if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
|
||||||
return Option.none();
|
return Option.none();
|
||||||
}
|
}
|
||||||
return Option.of(this.field[x][y]);
|
return Option.some(this.field[x][y]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public Tile getStartTile() {
|
public Tile getStartTile() {
|
||||||
return this.getTileAt(this.start).get();
|
return this.getTileAt(this.start).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public Tile getEndTile() {
|
public Tile getEndTile() {
|
||||||
return this.getTileAt(this.end).get();
|
return this.getTileAt(this.end).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NonNull
|
||||||
|
public String getRandomSeedStringRepresentation() {
|
||||||
|
return Long.toHexString(this.randomSeed);
|
||||||
|
}
|
||||||
|
|
||||||
private void initField() {
|
private void initField() {
|
||||||
for (int x = 0; x < this.width; x++) {
|
for (int x = 0; x < this.width; x++) {
|
||||||
this.field[x] = new Tile[this.height];
|
this.field[x] = new Tile[this.height];
|
||||||
|
|
@ -146,7 +151,7 @@ public class Maze {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void hardenWalls(@NotNull final Tile tile, final int x, final int y) {
|
private void hardenWalls(@NonNull final Tile tile, final int x, final int y) {
|
||||||
if (x == 0) {
|
if (x == 0) {
|
||||||
tile.preventDiggingToOrFrom(Direction.LEFT);
|
tile.preventDiggingToOrFrom(Direction.LEFT);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,12 @@ package ch.fritteli.maze.generator.model;
|
||||||
|
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import lombok.With;
|
import lombok.With;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
@With
|
@With
|
||||||
public record Position(int x, int y) {
|
public record Position(int x, int y) {
|
||||||
@NotNull
|
@NonNull
|
||||||
public Position move(@NotNull final Direction direction) {
|
public Position move(@NonNull final Direction direction) {
|
||||||
return switch (direction) {
|
return switch (direction) {
|
||||||
case BOTTOM -> this.withY(this.y + 1);
|
case BOTTOM -> this.withY(this.y + 1);
|
||||||
case LEFT -> this.withX(this.x - 1);
|
case LEFT -> this.withX(this.x - 1);
|
||||||
|
|
@ -16,8 +16,8 @@ public record Position(int x, int y) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public Option<Direction> getDirectionTo(@NotNull final Position position) {
|
public Option<Direction> getDirectionTo(@NonNull final Position position) {
|
||||||
final int xDiff = position.x - this.x;
|
final int xDiff = position.x - this.x;
|
||||||
final int yDiff = position.y - this.y;
|
final int yDiff = position.y - this.y;
|
||||||
return switch (xDiff) {
|
return switch (xDiff) {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import lombok.EqualsAndHashCode;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import lombok.experimental.FieldDefaults;
|
import lombok.experimental.FieldDefaults;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
@ -33,7 +33,7 @@ public class Tile {
|
||||||
* @param walls
|
* @param walls
|
||||||
* @param solution
|
* @param solution
|
||||||
*/
|
*/
|
||||||
private Tile(@NotNull final EnumSet<Direction> walls, final boolean solution) {
|
private Tile(@NonNull final EnumSet<Direction> walls, final boolean solution) {
|
||||||
for (final Direction direction : walls) {
|
for (final Direction direction : walls) {
|
||||||
this.walls.set(direction);
|
this.walls.set(direction);
|
||||||
this.walls.seal(direction);
|
this.walls.seal(direction);
|
||||||
|
|
@ -42,15 +42,15 @@ public class Tile {
|
||||||
this.solution = solution;
|
this.solution = solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void preventDiggingToOrFrom(@NotNull final Direction direction) {
|
public void preventDiggingToOrFrom(@NonNull final Direction direction) {
|
||||||
this.walls.seal(direction);
|
this.walls.seal(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableDiggingToOrFrom(@NotNull final Direction direction) {
|
public void enableDiggingToOrFrom(@NonNull final Direction direction) {
|
||||||
this.walls.unseal(direction);
|
this.walls.unseal(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean digFrom(@NotNull final Direction direction) {
|
public boolean digFrom(@NonNull final Direction direction) {
|
||||||
if (this.visited) {
|
if (this.visited) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -58,21 +58,21 @@ public class Tile {
|
||||||
return this.walls.clear(direction);
|
return this.walls.clear(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean digTo(@NotNull final Direction direction) {
|
public boolean digTo(@NonNull final Direction direction) {
|
||||||
return this.walls.clear(direction);
|
return this.walls.clear(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void undigTo(@NotNull final Direction direction) {
|
public void undigTo(@NonNull final Direction direction) {
|
||||||
this.walls.set(direction);
|
this.walls.set(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public EnumSet<Direction> getOpenDirections() {
|
public EnumSet<Direction> getOpenDirections() {
|
||||||
return this.walls.getOpen();
|
return this.walls.getOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public Option<Direction> getRandomAvailableDirection(@NotNull final Random random) {
|
public Option<Direction> getRandomAvailableDirection(@NonNull final Random random) {
|
||||||
final EnumSet<Direction> availableDirections = this.walls.getUnsealedSet();
|
final EnumSet<Direction> availableDirections = this.walls.getUnsealedSet();
|
||||||
if (availableDirections.isEmpty()) {
|
if (availableDirections.isEmpty()) {
|
||||||
return Option.none();
|
return Option.none();
|
||||||
|
|
@ -82,10 +82,10 @@ public class Tile {
|
||||||
}
|
}
|
||||||
final Vector<Direction> directions = Vector.ofAll(availableDirections);
|
final Vector<Direction> directions = Vector.ofAll(availableDirections);
|
||||||
final int index = random.nextInt(directions.size());
|
final int index = random.nextInt(directions.size());
|
||||||
return Option.of(directions.get(index));
|
return Option.some(directions.get(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasWallAt(@NotNull final Direction direction) {
|
public boolean hasWallAt(@NonNull final Direction direction) {
|
||||||
return this.walls.isSet(direction);
|
return this.walls.isSet(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package ch.fritteli.maze.generator.model;
|
||||||
|
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|
||||||
|
|
@ -13,7 +13,7 @@ public class Walls {
|
||||||
@EqualsAndHashCode.Exclude
|
@EqualsAndHashCode.Exclude
|
||||||
private final EnumSet<Direction> sealed = EnumSet.noneOf(Direction.class);
|
private final EnumSet<Direction> sealed = EnumSet.noneOf(Direction.class);
|
||||||
|
|
||||||
public void set(@NotNull final Direction direction) {
|
public void set(@NonNull final Direction direction) {
|
||||||
this.directions.add(direction);
|
this.directions.add(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -21,36 +21,36 @@ public class Walls {
|
||||||
this.directions.addAll(EnumSet.allOf(Direction.class));
|
this.directions.addAll(EnumSet.allOf(Direction.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean clear(@NotNull final Direction direction) {
|
public boolean clear(@NonNull final Direction direction) {
|
||||||
if (this.sealed.contains(direction)) {
|
if (this.sealed.contains(direction)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this.directions.remove(direction);
|
return this.directions.remove(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSet(@NotNull final Direction direction) {
|
public boolean isSet(@NonNull final Direction direction) {
|
||||||
return this.directions.contains(direction);
|
return this.directions.contains(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public EnumSet<Direction> getUnsealedSet() {
|
public EnumSet<Direction> getUnsealedSet() {
|
||||||
final EnumSet<Direction> result = EnumSet.copyOf(this.directions);
|
final EnumSet<Direction> result = EnumSet.copyOf(this.directions);
|
||||||
result.removeAll(this.sealed);
|
result.removeAll(this.sealed);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void seal(@NotNull final Direction direction) {
|
public void seal(@NonNull final Direction direction) {
|
||||||
if (!this.directions.contains(direction)) {
|
if (!this.directions.contains(direction)) {
|
||||||
throw new IllegalStateException("Trying to seal cleared Direction: " + direction);
|
throw new IllegalStateException("Trying to seal cleared Direction: " + direction);
|
||||||
}
|
}
|
||||||
this.sealed.add(direction);
|
this.sealed.add(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unseal(@NotNull final Direction direction) {
|
public void unseal(@NonNull final Direction direction) {
|
||||||
this.sealed.remove(direction);
|
this.sealed.remove(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public EnumSet<Direction> getOpen() {
|
public EnumSet<Direction> getOpen() {
|
||||||
return EnumSet.complementOf(this.directions);
|
return EnumSet.complementOf(this.directions);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
package ch.fritteli.maze.generator.renderer;
|
package ch.fritteli.maze.generator.renderer;
|
||||||
|
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
public interface Renderer<T> {
|
public interface Renderer<T> {
|
||||||
@NotNull
|
@NonNull
|
||||||
T render(@NotNull final Maze maze);
|
T render(@NonNull final Maze maze);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import io.vavr.collection.HashSet;
|
||||||
import io.vavr.collection.Set;
|
import io.vavr.collection.Set;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||||
class Generator {
|
class Generator {
|
||||||
|
|
@ -31,7 +31,7 @@ class Generator {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<String> getClasses(@NotNull final Tile tile) {
|
private Set<String> getClasses(@NonNull final Tile tile) {
|
||||||
Set<String> result = HashSet.empty();
|
Set<String> result = HashSet.empty();
|
||||||
if (tile.hasWallAt(Direction.TOP)) {
|
if (tile.hasWallAt(Direction.TOP)) {
|
||||||
result = result.add("top");
|
result = result.add("top");
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package ch.fritteli.maze.generator.renderer.html;
|
||||||
|
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.renderer.Renderer;
|
import ch.fritteli.maze.generator.renderer.Renderer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
public class HTMLRenderer implements Renderer<String> {
|
public class HTMLRenderer implements Renderer<String> {
|
||||||
|
|
||||||
|
|
@ -113,14 +113,14 @@ public class HTMLRenderer implements Renderer<String> {
|
||||||
private HTMLRenderer() {
|
private HTMLRenderer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public static HTMLRenderer newInstance() {
|
public static HTMLRenderer newInstance() {
|
||||||
return new HTMLRenderer();
|
return new HTMLRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String render(@NotNull final Maze maze) {
|
public String render(@NonNull final Maze maze) {
|
||||||
if (maze.getWidth() == 0 || maze.getHeight() == 0) {
|
if (maze.getWidth() == 0 || maze.getHeight() == 0) {
|
||||||
return this.getPreamble(maze) + POSTAMBLE;
|
return this.getPreamble(maze) + POSTAMBLE;
|
||||||
}
|
}
|
||||||
|
|
@ -135,12 +135,12 @@ public class HTMLRenderer implements Renderer<String> {
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getPreamble(@NotNull final Maze maze) {
|
private String getPreamble(@NonNull final Maze maze) {
|
||||||
return """
|
return """
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Maze %dx%d, ID %d, Algorithm %s</title>
|
<title>Maze %dx%d, ID %s, Algorithm %s</title>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<style>
|
<style>
|
||||||
table{border-collapse:collapse;}
|
table{border-collapse:collapse;}
|
||||||
|
|
@ -170,7 +170,7 @@ public class HTMLRenderer implements Renderer<String> {
|
||||||
.formatted(
|
.formatted(
|
||||||
maze.getWidth(),
|
maze.getWidth(),
|
||||||
maze.getHeight(),
|
maze.getHeight(),
|
||||||
maze.getRandomSeed(),
|
maze.getRandomSeedStringRepresentation(),
|
||||||
maze.getAlgorithm()
|
maze.getAlgorithm()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import ch.fritteli.maze.generator.renderer.html.HTMLRenderer;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import io.vavr.control.Try;
|
import io.vavr.control.Try;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -17,9 +17,9 @@ import java.util.NoSuchElementException;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class HTMLFileRenderer implements Renderer<Path> {
|
public class HTMLFileRenderer implements Renderer<Path> {
|
||||||
@NotNull
|
@NonNull
|
||||||
private static final HTMLRenderer HTML_RENDERER = HTMLRenderer.newInstance();
|
private static final HTMLRenderer HTML_RENDERER = HTMLRenderer.newInstance();
|
||||||
@NotNull
|
@NonNull
|
||||||
private Option<Path> targetFile;
|
private Option<Path> targetFile;
|
||||||
|
|
||||||
private HTMLFileRenderer() {
|
private HTMLFileRenderer() {
|
||||||
|
|
@ -29,7 +29,7 @@ public class HTMLFileRenderer implements Renderer<Path> {
|
||||||
.toOption();
|
.toOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public static HTMLFileRenderer newInstance() {
|
public static HTMLFileRenderer newInstance() {
|
||||||
return new HTMLFileRenderer();
|
return new HTMLFileRenderer();
|
||||||
}
|
}
|
||||||
|
|
@ -40,15 +40,15 @@ public class HTMLFileRenderer implements Renderer<Path> {
|
||||||
.exists(File::canWrite);
|
.exists(File::canWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public HTMLFileRenderer setTargetFile(@NotNull final Path targetFile) {
|
public HTMLFileRenderer setTargetFile(@NonNull final Path targetFile) {
|
||||||
this.targetFile = Option.of(targetFile);
|
this.targetFile = Option.some(targetFile);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Path render(@NotNull final Maze maze) {
|
public Path render(@NonNull final Maze maze) {
|
||||||
if (!this.isTargetFileDefinedAndWritable()) {
|
if (!this.isTargetFileDefinedAndWritable()) {
|
||||||
try {
|
try {
|
||||||
Files.createFile(this.targetFile.get());
|
Files.createFile(this.targetFile.get());
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.model.Tile;
|
import ch.fritteli.maze.generator.model.Tile;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
@ -16,13 +16,13 @@ import java.util.List;
|
||||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||||
class Generator {
|
class Generator {
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private final Maze maze;
|
private final Maze maze;
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
JsonMaze generate() {
|
JsonMaze generate() {
|
||||||
final JsonMaze result = new JsonMaze();
|
final JsonMaze result = new JsonMaze();
|
||||||
result.setId(String.valueOf(this.maze.getRandomSeed()));
|
result.setId(this.maze.getRandomSeedStringRepresentation());
|
||||||
result.setAlgorithm(this.maze.getAlgorithm());
|
result.setAlgorithm(this.maze.getAlgorithm());
|
||||||
result.setWidth(this.maze.getWidth());
|
result.setWidth(this.maze.getWidth());
|
||||||
result.setHeight(this.maze.getHeight());
|
result.setHeight(this.maze.getHeight());
|
||||||
|
|
|
||||||
|
|
@ -4,30 +4,30 @@ import ch.fritteli.maze.generator.json.JsonCell;
|
||||||
import ch.fritteli.maze.generator.json.JsonMaze;
|
import ch.fritteli.maze.generator.json.JsonMaze;
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.renderer.Renderer;
|
import ch.fritteli.maze.generator.renderer.Renderer;
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import org.jspecify.annotations.NonNull;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import tools.jackson.databind.SerializationFeature;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import tools.jackson.databind.json.JsonMapper;
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class JsonRenderer implements Renderer<String> {
|
public class JsonRenderer implements Renderer<String> {
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private final ObjectMapper objectMapper;
|
private final JsonMapper jsonMapper;
|
||||||
|
|
||||||
private JsonRenderer() {
|
private JsonRenderer() {
|
||||||
this.objectMapper = new ObjectMapper()
|
this.jsonMapper = JsonMapper.builder()
|
||||||
.enable(SerializationFeature.INDENT_OUTPUT);
|
.enable(SerializationFeature.INDENT_OUTPUT)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public static JsonRenderer newInstance() {
|
public static JsonRenderer newInstance() {
|
||||||
return new JsonRenderer();
|
return new JsonRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private static JsonMaze createSingleCellMaze() {
|
private static JsonMaze createSingleCellMaze() {
|
||||||
// This is the only cell.
|
// This is the only cell.
|
||||||
final JsonCell cell = new JsonCell();
|
final JsonCell cell = new JsonCell();
|
||||||
|
|
@ -45,18 +45,14 @@ public class JsonRenderer implements Renderer<String> {
|
||||||
return jsonMaze;
|
return jsonMaze;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private String toString(@NotNull final JsonMaze jsonMaze) {
|
private String toString(@NonNull final JsonMaze jsonMaze) {
|
||||||
try {
|
return this.jsonMapper.writeValueAsString(jsonMaze);
|
||||||
return this.objectMapper.writeValueAsString(jsonMaze);
|
|
||||||
} catch (final JsonProcessingException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String render(@NotNull final Maze maze) {
|
public String render(@NonNull final Maze maze) {
|
||||||
final JsonMaze jsonMaze;
|
final JsonMaze jsonMaze;
|
||||||
if (maze.getWidth() == 0 || maze.getHeight() == 0) {
|
if (maze.getWidth() == 0 || maze.getHeight() == 0) {
|
||||||
jsonMaze = createSingleCellMaze();
|
jsonMaze = createSingleCellMaze();
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import ch.fritteli.maze.generator.renderer.json.JsonRenderer;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import io.vavr.control.Try;
|
import io.vavr.control.Try;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -18,9 +18,9 @@ import java.util.NoSuchElementException;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class JsonFileRenderer implements Renderer<Path> {
|
public class JsonFileRenderer implements Renderer<Path> {
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private static final JsonRenderer JSON_RENDERER = JsonRenderer.newInstance();
|
private static final JsonRenderer JSON_RENDERER = JsonRenderer.newInstance();
|
||||||
@NotNull
|
@NonNull
|
||||||
private Option<Path> targetFile;
|
private Option<Path> targetFile;
|
||||||
|
|
||||||
private JsonFileRenderer() {
|
private JsonFileRenderer() {
|
||||||
|
|
@ -30,7 +30,7 @@ public class JsonFileRenderer implements Renderer<Path> {
|
||||||
.toOption();
|
.toOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public static JsonFileRenderer newInstance() {
|
public static JsonFileRenderer newInstance() {
|
||||||
return new JsonFileRenderer();
|
return new JsonFileRenderer();
|
||||||
}
|
}
|
||||||
|
|
@ -41,15 +41,15 @@ public class JsonFileRenderer implements Renderer<Path> {
|
||||||
.exists(File::canWrite);
|
.exists(File::canWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public JsonFileRenderer setTargetFile(@NotNull final Path targetFile) {
|
public JsonFileRenderer setTargetFile(@NonNull final Path targetFile) {
|
||||||
this.targetFile = Option.of(targetFile);
|
this.targetFile = Option.some(targetFile);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Path render(@NotNull final Maze maze) {
|
public Path render(@NonNull final Maze maze) {
|
||||||
if (!this.isTargetFileDefinedAndWritable()) {
|
if (!this.isTargetFileDefinedAndWritable()) {
|
||||||
try {
|
try {
|
||||||
Files.createFile(this.targetFile.get());
|
Files.createFile(this.targetFile.get());
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ import org.apache.pdfbox.pdmodel.PDDocumentInformation;
|
||||||
import org.apache.pdfbox.pdmodel.PDPage;
|
import org.apache.pdfbox.pdmodel.PDPage;
|
||||||
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
import org.apache.pdfbox.pdmodel.PDPageContentStream;
|
||||||
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
import org.apache.pdfbox.pdmodel.common.PDRectangle;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
@ -24,17 +24,22 @@ import java.io.IOException;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
class Generator {
|
class Generator {
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private final Maze maze;
|
private final Maze maze;
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public ByteArrayOutputStream generate() {
|
public ByteArrayOutputStream generate() {
|
||||||
final float pageWidth = this.maze.getWidth() * PDFRenderer.SCALE + 2 * PDFRenderer.MARGIN;
|
final float pageWidth = this.maze.getWidth() * PDFRenderer.SCALE + 2 * PDFRenderer.MARGIN;
|
||||||
final float pageHeight = this.maze.getHeight() * PDFRenderer.SCALE + 2 * PDFRenderer.MARGIN;
|
final float pageHeight = this.maze.getHeight() * PDFRenderer.SCALE + 2 * PDFRenderer.MARGIN;
|
||||||
|
|
||||||
final PDDocument pdDocument = new PDDocument();
|
final PDDocument pdDocument = new PDDocument();
|
||||||
final PDDocumentInformation info = new PDDocumentInformation();
|
final PDDocumentInformation info = new PDDocumentInformation();
|
||||||
info.setTitle("Maze %sx%s, ID %s (%s)".formatted(this.maze.getWidth(), this.maze.getHeight(), this.maze.getRandomSeed(), this.maze.getAlgorithm()));
|
info.setTitle("Maze %sx%s, ID %s (%s)".formatted(
|
||||||
|
this.maze.getWidth(),
|
||||||
|
this.maze.getHeight(),
|
||||||
|
this.maze.getRandomSeedStringRepresentation(),
|
||||||
|
this.maze.getAlgorithm()
|
||||||
|
));
|
||||||
pdDocument.setDocumentInformation(info);
|
pdDocument.setDocumentInformation(info);
|
||||||
final PDPage puzzlePage = new PDPage(new PDRectangle(pageWidth, pageHeight));
|
final PDPage puzzlePage = new PDPage(new PDRectangle(pageWidth, pageHeight));
|
||||||
final PDPage solutionPage = new PDPage(new PDRectangle(pageWidth, pageHeight));
|
final PDPage solutionPage = new PDPage(new PDRectangle(pageWidth, pageHeight));
|
||||||
|
|
@ -60,7 +65,7 @@ class Generator {
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setUpPageContentStream(@NotNull final PDPageContentStream pageContentStream) throws IOException {
|
private void setUpPageContentStream(@NonNull final PDPageContentStream pageContentStream) throws IOException {
|
||||||
pageContentStream.setLineCapStyle(BasicStroke.CAP_ROUND);
|
pageContentStream.setLineCapStyle(BasicStroke.CAP_ROUND);
|
||||||
pageContentStream.setLineJoinStyle(BasicStroke.JOIN_ROUND);
|
pageContentStream.setLineJoinStyle(BasicStroke.JOIN_ROUND);
|
||||||
pageContentStream.setLineWidth(1.0f);
|
pageContentStream.setLineWidth(1.0f);
|
||||||
|
|
@ -68,7 +73,7 @@ class Generator {
|
||||||
pageContentStream.setNonStrokingColor(Color.BLACK);
|
pageContentStream.setNonStrokingColor(Color.BLACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawHorizontalLines(@NotNull final PDPageContentStream... contentStreams) throws IOException {
|
private void drawHorizontalLines(@NonNull final PDPageContentStream... contentStreams) throws IOException {
|
||||||
// PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required.
|
// PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required.
|
||||||
Coordinate coordinate = new Coordinate(0f, 0f);
|
Coordinate coordinate = new Coordinate(0f, 0f);
|
||||||
// Draw the TOP borders of all tiles.
|
// Draw the TOP borders of all tiles.
|
||||||
|
|
@ -136,7 +141,7 @@ class Generator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawVerticalLines(@NotNull final PDPageContentStream... contentStreams) throws IOException {
|
private void drawVerticalLines(@NonNull final PDPageContentStream... contentStreams) throws IOException {
|
||||||
// PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required.
|
// PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required.
|
||||||
Coordinate coordinate = new Coordinate(0f, 0f);
|
Coordinate coordinate = new Coordinate(0f, 0f);
|
||||||
// Draw the LEFT borders of all tiles.
|
// Draw the LEFT borders of all tiles.
|
||||||
|
|
@ -204,7 +209,7 @@ class Generator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawSolution(@NotNull final PDPageContentStream pageContentStream) throws IOException {
|
private void drawSolution(@NonNull final PDPageContentStream pageContentStream) throws IOException {
|
||||||
// Draw the solution in red
|
// Draw the solution in red
|
||||||
pageContentStream.setStrokingColor(Color.RED);
|
pageContentStream.setStrokingColor(Color.RED);
|
||||||
// PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required.
|
// PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required.
|
||||||
|
|
@ -223,8 +228,8 @@ class Generator {
|
||||||
pageContentStream.stroke();
|
pageContentStream.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private Position findNextSolutionPosition(@Nullable final Position previousPosition, @NotNull final Position currentPosition) {
|
private Position findNextSolutionPosition(@Nullable final Position previousPosition, @NonNull final Position currentPosition) {
|
||||||
final Tile currentTile = this.maze.getTileAt(currentPosition).get();
|
final Tile currentTile = this.maze.getTileAt(currentPosition).get();
|
||||||
for (final Direction direction : Direction.values()) {
|
for (final Direction direction : Direction.values()) {
|
||||||
if (!currentTile.hasWallAt(direction)) {
|
if (!currentTile.hasWallAt(direction)) {
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package ch.fritteli.maze.generator.renderer.pdf;
|
||||||
|
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.renderer.Renderer;
|
import ch.fritteli.maze.generator.renderer.Renderer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
|
@ -13,14 +13,14 @@ public class PDFRenderer implements Renderer<ByteArrayOutputStream> {
|
||||||
private PDFRenderer() {
|
private PDFRenderer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public static PDFRenderer newInstance() {
|
public static PDFRenderer newInstance() {
|
||||||
return new PDFRenderer();
|
return new PDFRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public ByteArrayOutputStream render(@NotNull final Maze maze) {
|
public ByteArrayOutputStream render(@NonNull final Maze maze) {
|
||||||
final Generator generator = new Generator(maze);
|
final Generator generator = new Generator(maze);
|
||||||
return generator.generate();
|
return generator.generate();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import ch.fritteli.maze.generator.renderer.pdf.PDFRenderer;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import io.vavr.control.Try;
|
import io.vavr.control.Try;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -18,9 +18,9 @@ import java.util.NoSuchElementException;
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PDFFileRenderer implements Renderer<Path> {
|
public class PDFFileRenderer implements Renderer<Path> {
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private static final PDFRenderer PDF_RENDERER = PDFRenderer.newInstance();
|
private static final PDFRenderer PDF_RENDERER = PDFRenderer.newInstance();
|
||||||
@NotNull
|
@NonNull
|
||||||
private Option<Path> targetFile;
|
private Option<Path> targetFile;
|
||||||
|
|
||||||
private PDFFileRenderer() {
|
private PDFFileRenderer() {
|
||||||
|
|
@ -30,7 +30,7 @@ public class PDFFileRenderer implements Renderer<Path> {
|
||||||
.toOption();
|
.toOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public static PDFFileRenderer newInstance() {
|
public static PDFFileRenderer newInstance() {
|
||||||
return new PDFFileRenderer();
|
return new PDFFileRenderer();
|
||||||
}
|
}
|
||||||
|
|
@ -41,15 +41,15 @@ public class PDFFileRenderer implements Renderer<Path> {
|
||||||
.exists(File::canWrite);
|
.exists(File::canWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public PDFFileRenderer setTargetFile(@NotNull final Path targetFile) {
|
public PDFFileRenderer setTargetFile(@NonNull final Path targetFile) {
|
||||||
this.targetFile = Option.of(targetFile);
|
this.targetFile = Option.some(targetFile);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Path render(@NotNull final Maze maze) {
|
public Path render(@NonNull final Maze maze) {
|
||||||
if (!this.isTargetFileDefinedAndWritable()) {
|
if (!this.isTargetFileDefinedAndWritable()) {
|
||||||
try {
|
try {
|
||||||
Files.createFile(this.targetFile.get());
|
Files.createFile(this.targetFile.get());
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@ import ch.fritteli.maze.generator.model.Tile;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
|
||||||
class Generator {
|
class Generator {
|
||||||
@NotNull
|
@NonNull
|
||||||
private final Maze maze;
|
private final Maze maze;
|
||||||
private final boolean renderSolution;
|
private final boolean renderSolution;
|
||||||
private int x = 0;
|
private int x = 0;
|
||||||
|
|
@ -67,7 +67,7 @@ class Generator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String renderTopLine(@NotNull final Tile currentTile, @NotNull final Option<Tile> leftTile, @NotNull final Option<Tile> topTile) {
|
private String renderTopLine(@NonNull final Tile currentTile, @NonNull final Option<Tile> leftTile, @NonNull final Option<Tile> topTile) {
|
||||||
final CharDefinition charDef1 = new CharDefinition();
|
final CharDefinition charDef1 = new CharDefinition();
|
||||||
final CharDefinition charDef2 = new CharDefinition();
|
final CharDefinition charDef2 = new CharDefinition();
|
||||||
final CharDefinition charDef3 = new CharDefinition();
|
final CharDefinition charDef3 = new CharDefinition();
|
||||||
|
|
@ -103,11 +103,11 @@ class Generator {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String renderCenterLine(@NotNull final Tile currentTile,
|
private String renderCenterLine(@NonNull final Tile currentTile,
|
||||||
@NotNull final Option<Tile> topTile,
|
@NonNull final Option<Tile> topTile,
|
||||||
@NotNull final Option<Tile> rightTile,
|
@NonNull final Option<Tile> rightTile,
|
||||||
@NotNull final Option<Tile> bottomTile,
|
@NonNull final Option<Tile> bottomTile,
|
||||||
@NotNull final Option<Tile> leftTile) {
|
@NonNull final Option<Tile> leftTile) {
|
||||||
final CharDefinition charDef1 = new CharDefinition();
|
final CharDefinition charDef1 = new CharDefinition();
|
||||||
final CharDefinition charDef2 = new CharDefinition();
|
final CharDefinition charDef2 = new CharDefinition();
|
||||||
final CharDefinition charDef3 = new CharDefinition();
|
final CharDefinition charDef3 = new CharDefinition();
|
||||||
|
|
@ -151,7 +151,7 @@ class Generator {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String renderBottomLine(@NotNull final Tile currentTile, @NotNull final Option<Tile> leftTile) {
|
private String renderBottomLine(@NonNull final Tile currentTile, @NonNull final Option<Tile> leftTile) {
|
||||||
String result;
|
String result;
|
||||||
final CharDefinition charDef1 = new CharDefinition();
|
final CharDefinition charDef1 = new CharDefinition();
|
||||||
final CharDefinition charDef2 = new CharDefinition();
|
final CharDefinition charDef2 = new CharDefinition();
|
||||||
|
|
@ -184,15 +184,15 @@ class Generator {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasWallAt(@NotNull final Option<Tile> tile, @NotNull final Direction direction) {
|
private boolean hasWallAt(@NonNull final Option<Tile> tile, @NonNull final Direction direction) {
|
||||||
return tile.map(t -> t.hasWallAt(direction)).getOrElse(false);
|
return tile.map(t -> t.hasWallAt(direction)).getOrElse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSolution(@NotNull final Tile tile) {
|
private boolean isSolution(@NonNull final Tile tile) {
|
||||||
return this.renderSolution && tile.isSolution();
|
return this.renderSolution && tile.isSolution();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSolution(@NotNull final Option<Tile> tile) {
|
private boolean isSolution(@NonNull final Option<Tile> tile) {
|
||||||
return this.renderSolution && tile.map(Tile::isSolution).getOrElse(false);
|
return this.renderSolution && tile.map(Tile::isSolution).getOrElse(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ package ch.fritteli.maze.generator.renderer.text;
|
||||||
|
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.renderer.Renderer;
|
import ch.fritteli.maze.generator.renderer.Renderer;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
public class TextRenderer implements Renderer<String> {
|
public class TextRenderer implements Renderer<String> {
|
||||||
private boolean renderSolution;
|
private boolean renderSolution;
|
||||||
|
|
@ -11,20 +11,20 @@ public class TextRenderer implements Renderer<String> {
|
||||||
this.renderSolution = false;
|
this.renderSolution = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public static TextRenderer newInstance() {
|
public static TextRenderer newInstance() {
|
||||||
return new TextRenderer();
|
return new TextRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public TextRenderer setRenderSolution(final boolean renderSolution) {
|
public TextRenderer setRenderSolution(final boolean renderSolution) {
|
||||||
this.renderSolution = renderSolution;
|
this.renderSolution = renderSolution;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public String render(@NotNull final Maze maze) {
|
public String render(@NonNull final Maze maze) {
|
||||||
if (maze.getWidth() == 0 || maze.getHeight() == 0) {
|
if (maze.getWidth() == 0 || maze.getHeight() == 0) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import io.vavr.collection.List;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import io.vavr.control.Try;
|
import io.vavr.control.Try;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
@ -17,11 +17,11 @@ import java.util.NoSuchElementException;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class TextFileRenderer implements Renderer<List<Path>> {
|
public class TextFileRenderer implements Renderer<List<Path>> {
|
||||||
@NotNull
|
@NonNull
|
||||||
private static final TextRenderer TEXT_RENDERER = TextRenderer.newInstance();
|
private static final TextRenderer TEXT_RENDERER = TextRenderer.newInstance();
|
||||||
@NotNull
|
@NonNull
|
||||||
private Option<Path> targetMazeFile;
|
private Option<Path> targetMazeFile;
|
||||||
@NotNull
|
@NonNull
|
||||||
private Option<Path> targetSolutionFile;
|
private Option<Path> targetSolutionFile;
|
||||||
|
|
||||||
private TextFileRenderer() {
|
private TextFileRenderer() {
|
||||||
|
|
@ -41,7 +41,7 @@ public class TextFileRenderer implements Renderer<List<Path>> {
|
||||||
.toOption();
|
.toOption();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public static TextFileRenderer newInstance() {
|
public static TextFileRenderer newInstance() {
|
||||||
return new TextFileRenderer();
|
return new TextFileRenderer();
|
||||||
}
|
}
|
||||||
|
|
@ -58,21 +58,21 @@ public class TextFileRenderer implements Renderer<List<Path>> {
|
||||||
.exists(File::canWrite);
|
.exists(File::canWrite);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public TextFileRenderer setTargetMazeFile(@NotNull final Path targetMazeFile) {
|
public TextFileRenderer setTargetMazeFile(@NonNull final Path targetMazeFile) {
|
||||||
this.targetMazeFile = Option.of(targetMazeFile);
|
this.targetMazeFile = Option.some(targetMazeFile);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public TextFileRenderer setTargetSolutionFile(@NotNull final Path targetSolutionFile) {
|
public TextFileRenderer setTargetSolutionFile(@NonNull final Path targetSolutionFile) {
|
||||||
this.targetSolutionFile = Option.of(targetSolutionFile);
|
this.targetSolutionFile = Option.some(targetSolutionFile);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public List<Path> render(@NotNull final Maze maze) {
|
public List<Path> render(@NonNull final Maze maze) {
|
||||||
if (!this.isTargetMazeFileDefinedAndWritable()) {
|
if (!this.isTargetMazeFileDefinedAndWritable()) {
|
||||||
try {
|
try {
|
||||||
Files.createFile(this.targetMazeFile.get());
|
Files.createFile(this.targetMazeFile.get());
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
package ch.fritteli.maze.generator.serialization;
|
package ch.fritteli.maze.generator.serialization;
|
||||||
|
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public abstract class AbstractMazeInputStream extends ByteArrayInputStream {
|
public abstract class AbstractMazeInputStream extends ByteArrayInputStream {
|
||||||
|
|
||||||
public AbstractMazeInputStream(@NotNull final byte[] buf) {
|
public AbstractMazeInputStream(@NonNull final byte[] buf) {
|
||||||
super(buf);
|
super(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void checkHeader();
|
public abstract void checkHeader();
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public abstract Maze readMazeData() throws IOException;
|
public abstract Maze readMazeData() throws IOException;
|
||||||
|
|
||||||
public byte readByte() {
|
public byte readByte() {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
package ch.fritteli.maze.generator.serialization;
|
package ch.fritteli.maze.generator.serialization;
|
||||||
|
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@ public abstract class AbstractMazeOutputStream extends ByteArrayOutputStream {
|
||||||
|
|
||||||
public abstract void writeHeader();
|
public abstract void writeHeader();
|
||||||
|
|
||||||
public abstract void writeMazeData(@NotNull final Maze maze);
|
public abstract void writeMazeData(@NonNull final Maze maze);
|
||||||
|
|
||||||
public void writeByte(final byte value) {
|
public void writeByte(final byte value) {
|
||||||
this.write(value);
|
this.write(value);
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package ch.fritteli.maze.generator.serialization;
|
||||||
import ch.fritteli.maze.generator.model.Direction;
|
import ch.fritteli.maze.generator.model.Direction;
|
||||||
import ch.fritteli.maze.generator.model.Tile;
|
import ch.fritteli.maze.generator.model.Tile;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
@ -47,7 +47,7 @@ public class CommonTileHandler {
|
||||||
private final byte LEFT_BIT = 0b0000_1000;
|
private final byte LEFT_BIT = 0b0000_1000;
|
||||||
private final byte SOLUTION_BIT = 0b0001_0000;
|
private final byte SOLUTION_BIT = 0b0001_0000;
|
||||||
|
|
||||||
public byte getBitmaskForTile(@NotNull final Tile tile) {
|
public byte getBitmaskForTile(@NonNull final Tile tile) {
|
||||||
byte bitmask = 0;
|
byte bitmask = 0;
|
||||||
if (tile.hasWallAt(Direction.TOP)) {
|
if (tile.hasWallAt(Direction.TOP)) {
|
||||||
bitmask |= TOP_BIT;
|
bitmask |= TOP_BIT;
|
||||||
|
|
@ -67,7 +67,7 @@ public class CommonTileHandler {
|
||||||
return bitmask;
|
return bitmask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
public Tile getTileForBitmask(final byte bitmask) {
|
public Tile getTileForBitmask(final byte bitmask) {
|
||||||
final EnumSet<Direction> walls = EnumSet.noneOf(Direction.class);
|
final EnumSet<Direction> walls = EnumSet.noneOf(Direction.class);
|
||||||
if ((bitmask & TOP_BIT) == TOP_BIT) {
|
if ((bitmask & TOP_BIT) == TOP_BIT) {
|
||||||
|
|
@ -86,13 +86,13 @@ public class CommonTileHandler {
|
||||||
return createTile(walls, solution);
|
return createTile(walls, solution);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private Tile createTile(@NotNull final EnumSet<Direction> walls, boolean solution) {
|
private Tile createTile(@NonNull final EnumSet<Direction> walls, boolean solution) {
|
||||||
try {
|
try {
|
||||||
final Constructor<Tile> constructor = Tile.class.getDeclaredConstructor(EnumSet.class, Boolean.TYPE);
|
final Constructor<Tile> constructor = Tile.class.getDeclaredConstructor(EnumSet.class, Boolean.TYPE);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
return constructor.newInstance(walls, solution);
|
return constructor.newInstance(walls, solution);
|
||||||
} catch (@NotNull final NoSuchMethodException | InstantiationException | IllegalAccessException |
|
} catch (@NonNull final NoSuchMethodException | InstantiationException | IllegalAccessException |
|
||||||
InvocationTargetException e) {
|
InvocationTargetException e) {
|
||||||
throw new RuntimeException("Can not deserialize Tile from maze data.", e);
|
throw new RuntimeException("Can not deserialize Tile from maze data.", e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ import ch.fritteli.maze.generator.model.Tile;
|
||||||
import ch.fritteli.maze.generator.serialization.AbstractMazeInputStream;
|
import ch.fritteli.maze.generator.serialization.AbstractMazeInputStream;
|
||||||
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
||||||
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
public class MazeInputStreamV1 extends AbstractMazeInputStream {
|
public class MazeInputStreamV1 extends AbstractMazeInputStream {
|
||||||
|
|
||||||
public MazeInputStreamV1(@NotNull final byte[] buf) {
|
public MazeInputStreamV1(@NonNull final byte[] buf) {
|
||||||
super(buf);
|
super(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,7 +32,7 @@ public class MazeInputStreamV1 extends AbstractMazeInputStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Maze readMazeData() {
|
public Maze readMazeData() {
|
||||||
// 03..10 random seed number (long)
|
// 03..10 random seed number (long)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ import ch.fritteli.maze.generator.model.Tile;
|
||||||
import ch.fritteli.maze.generator.serialization.AbstractMazeOutputStream;
|
import ch.fritteli.maze.generator.serialization.AbstractMazeOutputStream;
|
||||||
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
||||||
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
public class MazeOutputStreamV1 extends AbstractMazeOutputStream {
|
public class MazeOutputStreamV1 extends AbstractMazeOutputStream {
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ public class MazeOutputStreamV1 extends AbstractMazeOutputStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeMazeData(@NotNull final Maze maze) {
|
public void writeMazeData(@NonNull final Maze maze) {
|
||||||
// 03..10 random seed number (long)
|
// 03..10 random seed number (long)
|
||||||
// 11..14 width (int)
|
// 11..14 width (int)
|
||||||
// 15..18 height (int)
|
// 15..18 height (int)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package ch.fritteli.maze.generator.serialization.v1;
|
||||||
import ch.fritteli.maze.generator.model.Maze;
|
import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.model.Tile;
|
import ch.fritteli.maze.generator.model.Tile;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
@ -32,8 +32,8 @@ public class SerializerDeserializerV1 {
|
||||||
* @param maze The {@link Maze} to be serialized.
|
* @param maze The {@link Maze} to be serialized.
|
||||||
* @return The resulting byte array.
|
* @return The resulting byte array.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
public byte[] serialize(@NotNull final Maze maze) {
|
public byte[] serialize(@NonNull final Maze maze) {
|
||||||
final MazeOutputStreamV1 stream = new MazeOutputStreamV1();
|
final MazeOutputStreamV1 stream = new MazeOutputStreamV1();
|
||||||
stream.writeHeader();
|
stream.writeHeader();
|
||||||
stream.writeMazeData(maze);
|
stream.writeMazeData(maze);
|
||||||
|
|
@ -46,20 +46,20 @@ public class SerializerDeserializerV1 {
|
||||||
* @param bytes The byte array to be deserialized.
|
* @param bytes The byte array to be deserialized.
|
||||||
* @return An instance of {@link Maze}.
|
* @return An instance of {@link Maze}.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
public Maze deserialize(@NotNull final byte[] bytes) {
|
public Maze deserialize(@NonNull final byte[] bytes) {
|
||||||
final MazeInputStreamV1 stream = new MazeInputStreamV1(bytes);
|
final MazeInputStreamV1 stream = new MazeInputStreamV1(bytes);
|
||||||
stream.checkHeader();
|
stream.checkHeader();
|
||||||
return stream.readMazeData();
|
return stream.readMazeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
Maze createMaze(@NotNull final Tile[][] field, final int width, final int height, final long randomSeed) {
|
Maze createMaze(@NonNull final Tile[][] field, final int width, final int height, final long randomSeed) {
|
||||||
try {
|
try {
|
||||||
final Constructor<Maze> constructor = Maze.class.getDeclaredConstructor(Tile[][].class, Integer.TYPE, Integer.TYPE, Long.TYPE);
|
final Constructor<Maze> constructor = Maze.class.getDeclaredConstructor(Tile[][].class, Integer.TYPE, Integer.TYPE, Long.TYPE);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
return constructor.newInstance(field, width, height, randomSeed);
|
return constructor.newInstance(field, width, height, randomSeed);
|
||||||
} catch (@NotNull final NoSuchMethodException | IllegalAccessException | InstantiationException |
|
} catch (@NonNull final NoSuchMethodException | IllegalAccessException | InstantiationException |
|
||||||
InvocationTargetException e) {
|
InvocationTargetException e) {
|
||||||
throw new RuntimeException("Can not deserialize Maze from maze data.", e);
|
throw new RuntimeException("Can not deserialize Maze from maze data.", e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,11 @@ import ch.fritteli.maze.generator.model.Tile;
|
||||||
import ch.fritteli.maze.generator.serialization.AbstractMazeInputStream;
|
import ch.fritteli.maze.generator.serialization.AbstractMazeInputStream;
|
||||||
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
||||||
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
public class MazeInputStreamV2 extends AbstractMazeInputStream {
|
public class MazeInputStreamV2 extends AbstractMazeInputStream {
|
||||||
|
|
||||||
public MazeInputStreamV2(@NotNull final byte[] buf) {
|
public MazeInputStreamV2(@NonNull final byte[] buf) {
|
||||||
super(buf);
|
super(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ public class MazeInputStreamV2 extends AbstractMazeInputStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Maze readMazeData() {
|
public Maze readMazeData() {
|
||||||
// 03..06 width (int)
|
// 03..06 width (int)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import ch.fritteli.maze.generator.model.Tile;
|
||||||
import ch.fritteli.maze.generator.serialization.AbstractMazeOutputStream;
|
import ch.fritteli.maze.generator.serialization.AbstractMazeOutputStream;
|
||||||
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
||||||
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
public class MazeOutputStreamV2 extends AbstractMazeOutputStream {
|
public class MazeOutputStreamV2 extends AbstractMazeOutputStream {
|
||||||
|
|
||||||
|
|
@ -21,7 +21,7 @@ public class MazeOutputStreamV2 extends AbstractMazeOutputStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeMazeData(@NotNull final Maze maze) {
|
public void writeMazeData(@NonNull final Maze maze) {
|
||||||
// 03..06 width (int)
|
// 03..06 width (int)
|
||||||
// 07..10 height (int)
|
// 07..10 height (int)
|
||||||
// 11..14 start-x (int)
|
// 11..14 start-x (int)
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.model.Position;
|
import ch.fritteli.maze.generator.model.Position;
|
||||||
import ch.fritteli.maze.generator.model.Tile;
|
import ch.fritteli.maze.generator.model.Tile;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
@ -37,8 +37,8 @@ public class SerializerDeserializerV2 {
|
||||||
* @param maze The {@link Maze} to be serialized.
|
* @param maze The {@link Maze} to be serialized.
|
||||||
* @return The resulting byte array.
|
* @return The resulting byte array.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
public byte[] serialize(@NotNull final Maze maze) {
|
public byte[] serialize(@NonNull final Maze maze) {
|
||||||
final MazeOutputStreamV2 stream = new MazeOutputStreamV2();
|
final MazeOutputStreamV2 stream = new MazeOutputStreamV2();
|
||||||
stream.writeHeader();
|
stream.writeHeader();
|
||||||
stream.writeMazeData(maze);
|
stream.writeMazeData(maze);
|
||||||
|
|
@ -51,20 +51,20 @@ public class SerializerDeserializerV2 {
|
||||||
* @param bytes The byte array to be deserialized.
|
* @param bytes The byte array to be deserialized.
|
||||||
* @return An instance of {@link Maze}.
|
* @return An instance of {@link Maze}.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
public Maze deserialize(@NotNull final byte[] bytes) {
|
public Maze deserialize(@NonNull final byte[] bytes) {
|
||||||
final MazeInputStreamV2 stream = new MazeInputStreamV2(bytes);
|
final MazeInputStreamV2 stream = new MazeInputStreamV2(bytes);
|
||||||
stream.checkHeader();
|
stream.checkHeader();
|
||||||
return stream.readMazeData();
|
return stream.readMazeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
Maze createMaze(@NotNull final Tile[][] field, final int width, final int height, @NotNull final Position start, @NotNull final Position end, final long randomSeed) {
|
Maze createMaze(@NonNull final Tile[][] field, final int width, final int height, @NonNull final Position start, @NonNull final Position end, final long randomSeed) {
|
||||||
try {
|
try {
|
||||||
final Constructor<Maze> constructor = Maze.class.getDeclaredConstructor(Tile[][].class, Integer.TYPE, Integer.TYPE, Position.class, Position.class, Long.TYPE);
|
final Constructor<Maze> constructor = Maze.class.getDeclaredConstructor(Tile[][].class, Integer.TYPE, Integer.TYPE, Position.class, Position.class, Long.TYPE);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
return constructor.newInstance(field, width, height, start, end, randomSeed);
|
return constructor.newInstance(field, width, height, start, end, randomSeed);
|
||||||
} catch (@NotNull final NoSuchMethodException | IllegalAccessException | InstantiationException |
|
} catch (@NonNull final NoSuchMethodException | IllegalAccessException | InstantiationException |
|
||||||
InvocationTargetException e) {
|
InvocationTargetException e) {
|
||||||
throw new RuntimeException("Can not deserialize Maze from maze data.", e);
|
throw new RuntimeException("Can not deserialize Maze from maze data.", e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@ import ch.fritteli.maze.generator.model.Tile;
|
||||||
import ch.fritteli.maze.generator.serialization.AbstractMazeInputStream;
|
import ch.fritteli.maze.generator.serialization.AbstractMazeInputStream;
|
||||||
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
||||||
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
public class MazeInputStreamV3 extends AbstractMazeInputStream {
|
public class MazeInputStreamV3 extends AbstractMazeInputStream {
|
||||||
|
|
||||||
public MazeInputStreamV3(@NotNull final byte[] buf) {
|
public MazeInputStreamV3(@NonNull final byte[] buf) {
|
||||||
super(buf);
|
super(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -36,7 +36,7 @@ public class MazeInputStreamV3 extends AbstractMazeInputStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public Maze readMazeData() throws IOException {
|
public Maze readMazeData() throws IOException {
|
||||||
// 03..06 width (int)
|
// 03..06 width (int)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import ch.fritteli.maze.generator.model.Tile;
|
||||||
import ch.fritteli.maze.generator.serialization.AbstractMazeOutputStream;
|
import ch.fritteli.maze.generator.serialization.AbstractMazeOutputStream;
|
||||||
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
import ch.fritteli.maze.generator.serialization.CommonTileHandler;
|
||||||
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
import ch.fritteli.maze.generator.serialization.MazeConstants;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
|
@ -23,7 +23,7 @@ public class MazeOutputStreamV3 extends AbstractMazeOutputStream {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeMazeData(@NotNull final Maze maze) {
|
public void writeMazeData(@NonNull final Maze maze) {
|
||||||
// 03..06 width (int)
|
// 03..06 width (int)
|
||||||
// 07..10 height (int)
|
// 07..10 height (int)
|
||||||
// 11..14 start-x (int)
|
// 11..14 start-x (int)
|
||||||
|
|
@ -60,8 +60,8 @@ public class MazeOutputStreamV3 extends AbstractMazeOutputStream {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
private AlgorithmWrapper getAlgorithmWrapper(@NotNull final String algorithm) {
|
private AlgorithmWrapper getAlgorithmWrapper(@NonNull final String algorithm) {
|
||||||
final byte[] bytes = algorithm.getBytes(StandardCharsets.UTF_8);
|
final byte[] bytes = algorithm.getBytes(StandardCharsets.UTF_8);
|
||||||
if (bytes.length < 256) {
|
if (bytes.length < 256) {
|
||||||
// Phew, that's the easy case!
|
// Phew, that's the easy case!
|
||||||
|
|
@ -81,6 +81,6 @@ public class MazeOutputStreamV3 extends AbstractMazeOutputStream {
|
||||||
return new AlgorithmWrapper(name, (byte) len);
|
return new AlgorithmWrapper(name, (byte) len);
|
||||||
}
|
}
|
||||||
|
|
||||||
private record AlgorithmWrapper(@NotNull byte[] name, byte length) {
|
private record AlgorithmWrapper(@NonNull byte[] name, byte length) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import ch.fritteli.maze.generator.model.Maze;
|
||||||
import ch.fritteli.maze.generator.model.Position;
|
import ch.fritteli.maze.generator.model.Position;
|
||||||
import ch.fritteli.maze.generator.model.Tile;
|
import ch.fritteli.maze.generator.model.Tile;
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NonNull;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
|
|
@ -40,8 +40,8 @@ public class SerializerDeserializerV3 {
|
||||||
* @param maze The {@link Maze} to be serialized.
|
* @param maze The {@link Maze} to be serialized.
|
||||||
* @return The resulting byte array.
|
* @return The resulting byte array.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
public byte[] serialize(@NotNull final Maze maze) {
|
public byte[] serialize(@NonNull final Maze maze) {
|
||||||
final MazeOutputStreamV3 stream = new MazeOutputStreamV3();
|
final MazeOutputStreamV3 stream = new MazeOutputStreamV3();
|
||||||
stream.writeHeader();
|
stream.writeHeader();
|
||||||
stream.writeMazeData(maze);
|
stream.writeMazeData(maze);
|
||||||
|
|
@ -54,21 +54,21 @@ public class SerializerDeserializerV3 {
|
||||||
* @param bytes The byte array to be deserialized.
|
* @param bytes The byte array to be deserialized.
|
||||||
* @return An instance of {@link Maze}.
|
* @return An instance of {@link Maze}.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NonNull
|
||||||
public Maze deserialize(@NotNull final byte[] bytes) throws IOException {
|
public Maze deserialize(@NonNull final byte[] bytes) throws IOException {
|
||||||
final MazeInputStreamV3 stream = new MazeInputStreamV3(bytes);
|
final MazeInputStreamV3 stream = new MazeInputStreamV3(bytes);
|
||||||
stream.checkHeader();
|
stream.checkHeader();
|
||||||
return stream.readMazeData();
|
return stream.readMazeData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NonNull
|
||||||
Maze createMaze(@NotNull final Tile[][] field,
|
Maze createMaze(@NonNull final Tile[][] field,
|
||||||
final int width,
|
final int width,
|
||||||
final int height,
|
final int height,
|
||||||
@NotNull final Position start,
|
@NonNull final Position start,
|
||||||
@NotNull final Position end,
|
@NonNull final Position end,
|
||||||
final long randomSeed,
|
final long randomSeed,
|
||||||
@NotNull final String algorithm) {
|
@NonNull final String algorithm) {
|
||||||
try {
|
try {
|
||||||
final Constructor<Maze> constructor = Maze.class.getDeclaredConstructor(
|
final Constructor<Maze> constructor = Maze.class.getDeclaredConstructor(
|
||||||
Tile[][].class,
|
Tile[][].class,
|
||||||
|
|
@ -81,7 +81,7 @@ public class SerializerDeserializerV3 {
|
||||||
);
|
);
|
||||||
constructor.setAccessible(true);
|
constructor.setAccessible(true);
|
||||||
return constructor.newInstance(field, width, height, start, end, randomSeed, algorithm);
|
return constructor.newInstance(field, width, height, start, end, randomSeed, algorithm);
|
||||||
} catch (@NotNull final NoSuchMethodException | IllegalAccessException | InstantiationException |
|
} catch (@NonNull final NoSuchMethodException | IllegalAccessException | InstantiationException |
|
||||||
InvocationTargetException e) {
|
InvocationTargetException e) {
|
||||||
throw new RuntimeException("Can not deserialize Maze from maze data.", e);
|
throw new RuntimeException("Can not deserialize Maze from maze data.", e);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
"description": "64 bit precision signed integer value. Transmitted as string, because ECMAScript (browsers) don't normally handle 64 bit integers well, as the ECMAScript 'number' type is a 64 bit signed double value, leaving only 53 bits for the integer part, thus losing precision."
|
"description": "64 bit precision unsigned integer value. Transmitted as a hexadecimal string."
|
||||||
},
|
},
|
||||||
"algorithm": {
|
"algorithm": {
|
||||||
"type": "string",
|
"type": "string",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package ch.fritteli.maze.generator.model;
|
package ch.fritteli.maze.generator.model;
|
||||||
|
|
||||||
import io.vavr.collection.Stream;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import java.util.EnumSet;
|
import java.util.EnumSet;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
package ch.fritteli.maze.generator.renderer.text;
|
package ch.fritteli.maze.generator.renderer.text;
|
||||||
|
|
||||||
import ch.fritteli.maze.generator.renderer.text.CharDefinition;
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue