Make TextRenderer and HTMLRenderer thread-safe (or so I think ...)
This commit is contained in:
parent
8774324b65
commit
cf96949f8e
5 changed files with 292 additions and 294 deletions
|
@ -9,6 +9,8 @@ import java.nio.file.Path;
|
||||||
import java.nio.file.StandardOpenOption;
|
import java.nio.file.StandardOpenOption;
|
||||||
|
|
||||||
public class HTMLFileRenderer implements Renderer<Path> {
|
public class HTMLFileRenderer implements Renderer<Path> {
|
||||||
|
@NonNull
|
||||||
|
private static final HTMLRenderer HTML_RENDERER = HTMLRenderer.newInstance();
|
||||||
@Setter
|
@Setter
|
||||||
private Path targetFile;
|
private Path targetFile;
|
||||||
|
|
||||||
|
@ -35,7 +37,7 @@ public class HTMLFileRenderer implements Renderer<Path> {
|
||||||
if (!this.isTargetFileDefinedAndWritable()) {
|
if (!this.isTargetFileDefinedAndWritable()) {
|
||||||
throw new IllegalArgumentException("Cannot write to target file. See previous log messages for details.");
|
throw new IllegalArgumentException("Cannot write to target file. See previous log messages for details.");
|
||||||
}
|
}
|
||||||
final String html = HTMLRenderer.newInstance().render(labyrinth);
|
final String html = HTML_RENDERER.render(labyrinth);
|
||||||
try {
|
try {
|
||||||
Files.writeString(this.targetFile, html, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
|
Files.writeString(this.targetFile, html, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ch.fritteli.labyrinth;
|
||||||
import io.vavr.collection.HashSet;
|
import io.vavr.collection.HashSet;
|
||||||
import io.vavr.collection.Set;
|
import io.vavr.collection.Set;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
|
||||||
public class HTMLRenderer implements Renderer<String> {
|
public class HTMLRenderer implements Renderer<String> {
|
||||||
private static final String PREAMBLE = "<!DOCTYPE html><html lang=\"en\">" +
|
private static final String PREAMBLE = "<!DOCTYPE html><html lang=\"en\">" +
|
||||||
|
@ -33,11 +34,6 @@ public class HTMLRenderer implements Renderer<String> {
|
||||||
"<body>" +
|
"<body>" +
|
||||||
"<input type=\"checkbox\" onclick=\"toggleSolution()\">show solution</input>";
|
"<input type=\"checkbox\" onclick=\"toggleSolution()\">show solution</input>";
|
||||||
private static final String POSTAMBLE = "</body></html>";
|
private static final String POSTAMBLE = "</body></html>";
|
||||||
private Labyrinth labyrinth;
|
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
// row counter
|
|
||||||
private int y = 0;
|
|
||||||
|
|
||||||
private HTMLRenderer() {
|
private HTMLRenderer() {
|
||||||
}
|
}
|
||||||
|
@ -49,56 +45,60 @@ public class HTMLRenderer implements Renderer<String> {
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public String render(@NonNull final Labyrinth labyrinth) {
|
public String render(@NonNull final Labyrinth labyrinth) {
|
||||||
this.labyrinth = labyrinth;
|
if (labyrinth.getWidth() == 0 || labyrinth.getHeight() == 0) {
|
||||||
this.width = labyrinth.getWidth();
|
|
||||||
this.height = labyrinth.getHeight();
|
|
||||||
if (this.width == 0 || this.height == 0) {
|
|
||||||
return PREAMBLE + POSTAMBLE;
|
return PREAMBLE + POSTAMBLE;
|
||||||
}
|
}
|
||||||
|
final Generator generator = new Generator(labyrinth);
|
||||||
final StringBuilder sb = new StringBuilder(PREAMBLE);
|
final StringBuilder sb = new StringBuilder(PREAMBLE);
|
||||||
sb.append("<table>");
|
sb.append("<table>");
|
||||||
while (this.hasNext()) {
|
while (generator.hasNext()) {
|
||||||
sb.append(this.next());
|
sb.append(generator.next());
|
||||||
}
|
}
|
||||||
sb.append("</table>");
|
sb.append("</table>");
|
||||||
sb.append(POSTAMBLE);
|
sb.append(POSTAMBLE);
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasNext() {
|
@RequiredArgsConstructor
|
||||||
return this.y < this.height;
|
private static class Generator {
|
||||||
}
|
private final Labyrinth labyrinth;
|
||||||
|
private int y = 0;
|
||||||
|
|
||||||
private String next() {
|
private boolean hasNext() {
|
||||||
StringBuilder sb = new StringBuilder("<tr>");
|
return this.y < this.labyrinth.getHeight();
|
||||||
for (int x = 0; x < this.width; x++) {
|
|
||||||
final Tile currentTile = this.labyrinth.getTileAt(x, this.y);
|
|
||||||
sb.append("<td class=\"");
|
|
||||||
sb.append(this.getClasses(currentTile).mkString(" "));
|
|
||||||
sb.append("\"> </td>");
|
|
||||||
}
|
}
|
||||||
sb.append("</tr>");
|
|
||||||
this.y++;
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<String> getClasses(@NonNull final Tile tile) {
|
private String next() {
|
||||||
Set<String> result = HashSet.empty();
|
StringBuilder sb = new StringBuilder("<tr>");
|
||||||
if (tile.hasWallAt(Direction.TOP)) {
|
for (int x = 0; x < this.labyrinth.getWidth(); x++) {
|
||||||
result = result.add("top");
|
final Tile currentTile = this.labyrinth.getTileAt(x, this.y);
|
||||||
|
sb.append("<td class=\"");
|
||||||
|
sb.append(this.getClasses(currentTile).mkString(" "));
|
||||||
|
sb.append("\"> </td>");
|
||||||
|
}
|
||||||
|
sb.append("</tr>");
|
||||||
|
this.y++;
|
||||||
|
return sb.toString();
|
||||||
}
|
}
|
||||||
if (tile.hasWallAt(Direction.RIGHT)) {
|
|
||||||
result = result.add("right");
|
private Set<String> getClasses(@NonNull final Tile tile) {
|
||||||
|
Set<String> result = HashSet.empty();
|
||||||
|
if (tile.hasWallAt(Direction.TOP)) {
|
||||||
|
result = result.add("top");
|
||||||
|
}
|
||||||
|
if (tile.hasWallAt(Direction.RIGHT)) {
|
||||||
|
result = result.add("right");
|
||||||
|
}
|
||||||
|
if (tile.hasWallAt(Direction.BOTTOM)) {
|
||||||
|
result = result.add("bottom");
|
||||||
|
}
|
||||||
|
if (tile.hasWallAt(Direction.LEFT)) {
|
||||||
|
result = result.add("left");
|
||||||
|
}
|
||||||
|
if (tile.isSolution()) {
|
||||||
|
result = result.add("solution");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
if (tile.hasWallAt(Direction.BOTTOM)) {
|
|
||||||
result = result.add("bottom");
|
|
||||||
}
|
|
||||||
if (tile.hasWallAt(Direction.LEFT)) {
|
|
||||||
result = result.add("left");
|
|
||||||
}
|
|
||||||
if (tile.isSolution()) {
|
|
||||||
result = result.add("solution");
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ public class Main {
|
||||||
final Labyrinth labyrinth = new Labyrinth(width, height);
|
final Labyrinth labyrinth = new Labyrinth(width, height);
|
||||||
final TextRenderer textRenderer = TextRenderer.newInstance();
|
final TextRenderer textRenderer = TextRenderer.newInstance();
|
||||||
System.out.println(textRenderer.render(labyrinth));
|
System.out.println(textRenderer.render(labyrinth));
|
||||||
System.out.println(textRenderer.setRenderingSolution(true).render(labyrinth));
|
System.out.println(textRenderer.setRenderSolution(true).render(labyrinth));
|
||||||
final HTMLRenderer htmlRenderer = HTMLRenderer.newInstance();
|
final HTMLRenderer htmlRenderer = HTMLRenderer.newInstance();
|
||||||
System.out.println(htmlRenderer.render(labyrinth));
|
System.out.println(htmlRenderer.render(labyrinth));
|
||||||
System.out.println(HTMLFileRenderer.newInstance().render(labyrinth));
|
System.out.println(HTMLFileRenderer.newInstance().render(labyrinth));
|
||||||
|
|
|
@ -4,20 +4,12 @@ import lombok.AccessLevel;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.experimental.FieldDefaults;
|
import lombok.experimental.FieldDefaults;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
public class TextRenderer implements Renderer<String> {
|
public class TextRenderer implements Renderer<String> {
|
||||||
private Labyrinth labyrinth;
|
|
||||||
private int width;
|
|
||||||
private int height;
|
|
||||||
private boolean renderSolution;
|
private boolean renderSolution;
|
||||||
// column counter
|
|
||||||
private int x;
|
|
||||||
// row counter
|
|
||||||
private int y;
|
|
||||||
// line counter (top-, center- or bottom line of a row)
|
|
||||||
private int line;
|
|
||||||
|
|
||||||
private TextRenderer() {
|
private TextRenderer() {
|
||||||
this.renderSolution = false;
|
this.renderSolution = false;
|
||||||
|
@ -29,295 +21,299 @@ public class TextRenderer implements Renderer<String> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public TextRenderer setRenderingSolution(final boolean renderSolution) {
|
public TextRenderer setRenderSolution(final boolean renderSolution) {
|
||||||
this.renderSolution = renderSolution;
|
this.renderSolution = renderSolution;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
public String render(@NonNull final Labyrinth labyrinth) {
|
public String render(@NonNull final Labyrinth labyrinth) {
|
||||||
this.labyrinth = labyrinth;
|
if (labyrinth.getWidth() == 0 || labyrinth.getHeight() == 0) {
|
||||||
this.width = labyrinth.getWidth();
|
|
||||||
this.height = labyrinth.getHeight();
|
|
||||||
if (this.width == 0 || this.height == 0) {
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
this.x = 0;
|
final Generator generator = new Generator(labyrinth, this.renderSolution);
|
||||||
this.y = 0;
|
|
||||||
this.line = 0;
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
final StringBuilder sb = new StringBuilder();
|
||||||
while (this.hasNext()) {
|
while (generator.hasNext()) {
|
||||||
sb.append(this.next());
|
sb.append(generator.next());
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasNext() {
|
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
return this.y < this.height;
|
static class Generator {
|
||||||
}
|
@NonNull
|
||||||
|
private final Labyrinth labyrinth;
|
||||||
|
private final boolean renderSolution;
|
||||||
|
private int x = 0;
|
||||||
|
private int y = 0;
|
||||||
|
private int line = 0;
|
||||||
|
|
||||||
private String next() {
|
private boolean hasNext() {
|
||||||
final Tile currentTile = this.labyrinth.getTileAt(this.x, this.y);
|
return this.y < this.labyrinth.getHeight();
|
||||||
final Tile leftTile = this.getTileOrNull(this.x - 1, this.y);
|
|
||||||
final Tile topTile = this.getTileOrNull(this.x, this.y - 1);
|
|
||||||
final String s;
|
|
||||||
switch (this.line) {
|
|
||||||
case 0:
|
|
||||||
s = this.renderTopLine(currentTile, leftTile, topTile);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
s = this.renderCenterLine(currentTile);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
s = this.renderBottomLine(currentTile, leftTile);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
s = "";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
this.prepareNextStep();
|
|
||||||
return s;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void prepareNextStep() {
|
private String next() {
|
||||||
// do some magic ...
|
final Tile currentTile = this.labyrinth.getTileAt(this.x, this.y);
|
||||||
this.x++;
|
final Tile leftTile = this.getTileOrNull(this.x - 1, this.y);
|
||||||
if (this.x == this.width) {
|
final Tile topTile = this.getTileOrNull(this.x, this.y - 1);
|
||||||
// Reached the end of the row?
|
final String s;
|
||||||
// On to the next line then!
|
switch (this.line) {
|
||||||
this.x = 0;
|
case 0:
|
||||||
this.line++;
|
s = this.renderTopLine(currentTile, leftTile, topTile);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
s = this.renderCenterLine(currentTile);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
s = this.renderBottomLine(currentTile, leftTile);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.prepareNextStep();
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
if (this.line == 2 && this.y < this.height - 1) {
|
|
||||||
// Finished rendering the center line, and more rows available?
|
|
||||||
// On to the next row then!
|
|
||||||
this.line = 0;
|
|
||||||
this.y++;
|
|
||||||
}
|
|
||||||
if (this.line == 3) {
|
|
||||||
// Finished rendering the bottom line (of the last row)?
|
|
||||||
// Increment row counter one more time => this is the exit condition.
|
|
||||||
this.line = 0;
|
|
||||||
this.y++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Tile getTileOrNull(final int x, final int y) {
|
private void prepareNextStep() {
|
||||||
if (x < 0 || y < 0 || x >= this.width || y >= this.height) {
|
// do some magic ...
|
||||||
return null;
|
this.x++;
|
||||||
|
if (this.x == this.labyrinth.getWidth()) {
|
||||||
|
// Reached the end of the row?
|
||||||
|
// On to the next line then!
|
||||||
|
this.x = 0;
|
||||||
|
this.line++;
|
||||||
|
}
|
||||||
|
if (this.line == 2 && this.y < this.labyrinth.getHeight() - 1) {
|
||||||
|
// Finished rendering the center line, and more rows available?
|
||||||
|
// On to the next row then!
|
||||||
|
this.line = 0;
|
||||||
|
this.y++;
|
||||||
|
}
|
||||||
|
if (this.line == 3) {
|
||||||
|
// Finished rendering the bottom line (of the last row)?
|
||||||
|
// Increment row counter one more time => this is the exit condition.
|
||||||
|
this.line = 0;
|
||||||
|
this.y++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this.labyrinth.getTileAt(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
private String renderTopLine(@NonNull final Tile currentTile, @Nullable final Tile leftTile, @Nullable final Tile topTile) {
|
private Tile getTileOrNull(final int x, final int y) {
|
||||||
final CharDefinition charDef1 = new CharDefinition();
|
if (x < 0 || y < 0 || x >= this.labyrinth.getWidth() || y >= this.labyrinth.getHeight()) {
|
||||||
final CharDefinition charDef2 = new CharDefinition();
|
return null;
|
||||||
final CharDefinition charDef3 = new CharDefinition();
|
}
|
||||||
String result;
|
return this.labyrinth.getTileAt(x, y);
|
||||||
if (currentTile.hasWallAt(Direction.LEFT)) {
|
|
||||||
charDef1.down();
|
|
||||||
}
|
}
|
||||||
if (currentTile.hasWallAt(Direction.TOP)) {
|
|
||||||
charDef1.right();
|
private String renderTopLine(@NonNull final Tile currentTile, @Nullable final Tile leftTile, @Nullable final Tile topTile) {
|
||||||
charDef2.horizontal();
|
final CharDefinition charDef1 = new CharDefinition();
|
||||||
charDef3.left();
|
final CharDefinition charDef2 = new CharDefinition();
|
||||||
|
final CharDefinition charDef3 = new CharDefinition();
|
||||||
|
String result;
|
||||||
|
if (currentTile.hasWallAt(Direction.LEFT)) {
|
||||||
|
charDef1.down();
|
||||||
|
}
|
||||||
|
if (currentTile.hasWallAt(Direction.TOP)) {
|
||||||
|
charDef1.right();
|
||||||
|
charDef2.horizontal();
|
||||||
|
charDef3.left();
|
||||||
|
}
|
||||||
|
if (currentTile.hasWallAt(Direction.RIGHT)) {
|
||||||
|
charDef3.down();
|
||||||
|
}
|
||||||
|
if (leftTile != null && leftTile.hasWallAt(Direction.TOP)) {
|
||||||
|
charDef1.left();
|
||||||
|
}
|
||||||
|
if (topTile != null) {
|
||||||
|
if (topTile.hasWallAt(Direction.LEFT)) {
|
||||||
|
charDef1.up();
|
||||||
|
}
|
||||||
|
if (topTile.hasWallAt(Direction.RIGHT)) {
|
||||||
|
charDef3.up();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = charDef1.toString() + charDef2;
|
||||||
|
if (this.x == this.labyrinth.getWidth() - 1) {
|
||||||
|
result += charDef3 + "\n";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
if (currentTile.hasWallAt(Direction.RIGHT)) {
|
|
||||||
charDef3.down();
|
private String renderCenterLine(@NonNull final Tile currentTile) {
|
||||||
|
final CharDefinition charDef1 = new CharDefinition();
|
||||||
|
final CharDefinition charDef2 = new CharDefinition();
|
||||||
|
String result;
|
||||||
|
if (currentTile.hasWallAt(Direction.LEFT)) {
|
||||||
|
charDef1.vertical();
|
||||||
|
}
|
||||||
|
if (currentTile.hasWallAt(Direction.RIGHT)) {
|
||||||
|
charDef2.vertical();
|
||||||
|
}
|
||||||
|
|
||||||
|
result = charDef1 + (currentTile.isSolution() && this.renderSolution ? "x" : " ");
|
||||||
|
|
||||||
|
if (this.x == this.labyrinth.getWidth() - 1) {
|
||||||
|
result += charDef2 + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
if (leftTile != null && leftTile.hasWallAt(Direction.TOP)) {
|
|
||||||
charDef1.left();
|
private String renderBottomLine(@NonNull final Tile currentTile, @Nullable final Tile leftTile) {
|
||||||
}
|
String result;
|
||||||
if (topTile != null) {
|
final CharDefinition charDef1 = new CharDefinition();
|
||||||
if (topTile.hasWallAt(Direction.LEFT)) {
|
final CharDefinition charDef2 = new CharDefinition();
|
||||||
|
final CharDefinition charDef3 = new CharDefinition();
|
||||||
|
|
||||||
|
if (currentTile.hasWallAt(Direction.LEFT)) {
|
||||||
charDef1.up();
|
charDef1.up();
|
||||||
}
|
}
|
||||||
if (topTile.hasWallAt(Direction.RIGHT)) {
|
if (currentTile.hasWallAt(Direction.BOTTOM)) {
|
||||||
|
charDef1.right();
|
||||||
|
charDef2.horizontal();
|
||||||
|
charDef3.left();
|
||||||
|
}
|
||||||
|
if (currentTile.hasWallAt(Direction.RIGHT)) {
|
||||||
charDef3.up();
|
charDef3.up();
|
||||||
}
|
}
|
||||||
}
|
if (leftTile != null && leftTile.hasWallAt(Direction.BOTTOM)) {
|
||||||
result = charDef1.toString() + charDef2;
|
charDef1.left();
|
||||||
if (this.x == this.width - 1) {
|
}
|
||||||
result += charDef3 + "\n";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String renderCenterLine(@NonNull final Tile currentTile) {
|
result = charDef1.toString() + charDef2;
|
||||||
final CharDefinition charDef1 = new CharDefinition();
|
|
||||||
final CharDefinition charDef2 = new CharDefinition();
|
if (this.x == this.labyrinth.getWidth() - 1) {
|
||||||
String result;
|
result += charDef3;
|
||||||
if (currentTile.hasWallAt(Direction.LEFT)) {
|
}
|
||||||
charDef1.vertical();
|
return result;
|
||||||
}
|
|
||||||
if (currentTile.hasWallAt(Direction.RIGHT)) {
|
|
||||||
charDef2.vertical();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = charDef1 + (currentTile.isSolution() && this.renderSolution ? "x" : " ");
|
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
static class CharDefinition {
|
||||||
|
// ─
|
||||||
|
static final String HORIZONTAL = "\u2500";
|
||||||
|
// │
|
||||||
|
static final String VERTICAL = "\u2502";
|
||||||
|
// ╴
|
||||||
|
static final String LEFT = "\u2574";
|
||||||
|
// ╵
|
||||||
|
static final String UP = "\u2575";
|
||||||
|
// ╶
|
||||||
|
static final String RIGHT = "\u2576";
|
||||||
|
// ╷
|
||||||
|
static final String DOWN = "\u2577";
|
||||||
|
// ┌
|
||||||
|
static final String DOWN_RIGHT = "\u250c";
|
||||||
|
// ┐
|
||||||
|
static final String DOWN_LEFT = "\u2510";
|
||||||
|
// └
|
||||||
|
static final String UP_RIGHT = "\u2514";
|
||||||
|
// ┘
|
||||||
|
static final String UP_LEFT = "\u2518";
|
||||||
|
// ├
|
||||||
|
static final String VERTICAL_RIGHT = "\u251c";
|
||||||
|
// ┤
|
||||||
|
static final String VERTICAL_LEFT = "\u2524";
|
||||||
|
// ┬
|
||||||
|
static final String HORIZONTAL_DOWN = "\u252c";
|
||||||
|
// ┴
|
||||||
|
static final String HORIZONTAL_UP = "\u2534";
|
||||||
|
// ┼
|
||||||
|
static final String CROSS = "\u253c";
|
||||||
|
boolean up = false;
|
||||||
|
boolean down = false;
|
||||||
|
boolean left = false;
|
||||||
|
boolean right = false;
|
||||||
|
|
||||||
if (this.x == this.width - 1) {
|
CharDefinition up() {
|
||||||
result += charDef2 + "\n";
|
this.up = true;
|
||||||
}
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
CharDefinition down() {
|
||||||
}
|
this.down = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private String renderBottomLine(@NonNull final Tile currentTile, @Nullable final Tile leftTile) {
|
CharDefinition vertical() {
|
||||||
String result;
|
return this.up().down();
|
||||||
final CharDefinition charDef1 = new CharDefinition();
|
}
|
||||||
final CharDefinition charDef2 = new CharDefinition();
|
|
||||||
final CharDefinition charDef3 = new CharDefinition();
|
|
||||||
|
|
||||||
if (currentTile.hasWallAt(Direction.LEFT)) {
|
CharDefinition left() {
|
||||||
charDef1.up();
|
this.left = true;
|
||||||
}
|
return this;
|
||||||
if (currentTile.hasWallAt(Direction.BOTTOM)) {
|
}
|
||||||
charDef1.right();
|
|
||||||
charDef2.horizontal();
|
|
||||||
charDef3.left();
|
|
||||||
}
|
|
||||||
if (currentTile.hasWallAt(Direction.RIGHT)) {
|
|
||||||
charDef3.up();
|
|
||||||
}
|
|
||||||
if (leftTile != null && leftTile.hasWallAt(Direction.BOTTOM)) {
|
|
||||||
charDef1.left();
|
|
||||||
}
|
|
||||||
|
|
||||||
result = charDef1.toString() + charDef2;
|
CharDefinition right() {
|
||||||
|
this.right = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.x == this.width - 1) {
|
CharDefinition horizontal() {
|
||||||
result += charDef3;
|
return this.left().right();
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
public String toString() {
|
||||||
@NoArgsConstructor
|
if (this.up) {
|
||||||
@AllArgsConstructor
|
if (this.down) {
|
||||||
static class CharDefinition {
|
if (this.left) {
|
||||||
// ─
|
if (this.right) {
|
||||||
static final String HORIZONTAL = "\u2500";
|
return CROSS;
|
||||||
// │
|
} else {
|
||||||
static final String VERTICAL = "\u2502";
|
return VERTICAL_LEFT;
|
||||||
// ╴
|
}
|
||||||
static final String LEFT = "\u2574";
|
|
||||||
// ╵
|
|
||||||
static final String UP = "\u2575";
|
|
||||||
// ╶
|
|
||||||
static final String RIGHT = "\u2576";
|
|
||||||
// ╷
|
|
||||||
static final String DOWN = "\u2577";
|
|
||||||
// ┌
|
|
||||||
static final String DOWN_RIGHT = "\u250c";
|
|
||||||
// ┐
|
|
||||||
static final String DOWN_LEFT = "\u2510";
|
|
||||||
// └
|
|
||||||
static final String UP_RIGHT = "\u2514";
|
|
||||||
// ┘
|
|
||||||
static final String UP_LEFT = "\u2518";
|
|
||||||
// ├
|
|
||||||
static final String VERTICAL_RIGHT = "\u251c";
|
|
||||||
// ┤
|
|
||||||
static final String VERTICAL_LEFT = "\u2524";
|
|
||||||
// ┬
|
|
||||||
static final String HORIZONTAL_DOWN = "\u252c";
|
|
||||||
// ┴
|
|
||||||
static final String HORIZONTAL_UP = "\u2534";
|
|
||||||
// ┼
|
|
||||||
static final String CROSS = "\u253c";
|
|
||||||
boolean up = false;
|
|
||||||
boolean down = false;
|
|
||||||
boolean left = false;
|
|
||||||
boolean right = false;
|
|
||||||
|
|
||||||
CharDefinition up() {
|
|
||||||
this.up = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
CharDefinition down() {
|
|
||||||
this.down = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
CharDefinition vertical() {
|
|
||||||
return this.up().down();
|
|
||||||
}
|
|
||||||
|
|
||||||
CharDefinition left() {
|
|
||||||
this.left = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
CharDefinition right() {
|
|
||||||
this.right = true;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
CharDefinition horizontal() {
|
|
||||||
return this.left().right();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
if (this.up) {
|
|
||||||
if (this.down) {
|
|
||||||
if (this.left) {
|
|
||||||
if (this.right) {
|
|
||||||
return CROSS;
|
|
||||||
} else {
|
} else {
|
||||||
return VERTICAL_LEFT;
|
if (this.right) {
|
||||||
|
return VERTICAL_RIGHT;
|
||||||
|
} else {
|
||||||
|
return VERTICAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.right) {
|
if (this.left) {
|
||||||
return VERTICAL_RIGHT;
|
if (this.right) {
|
||||||
|
return HORIZONTAL_UP;
|
||||||
|
} else {
|
||||||
|
return UP_LEFT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return VERTICAL;
|
if (this.right) {
|
||||||
|
return UP_RIGHT;
|
||||||
|
} else {
|
||||||
|
return UP;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.left) {
|
if (this.down) {
|
||||||
if (this.right) {
|
if (this.left) {
|
||||||
return HORIZONTAL_UP;
|
if (this.right) {
|
||||||
|
return HORIZONTAL_DOWN;
|
||||||
|
} else {
|
||||||
|
return DOWN_LEFT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return UP_LEFT;
|
if (this.right) {
|
||||||
|
return DOWN_RIGHT;
|
||||||
|
} else {
|
||||||
|
return DOWN;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (this.right) {
|
if (this.left) {
|
||||||
return UP_RIGHT;
|
if (this.right) {
|
||||||
|
return HORIZONTAL;
|
||||||
|
} else {
|
||||||
|
return LEFT;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return UP;
|
if (this.right) {
|
||||||
}
|
return RIGHT;
|
||||||
}
|
} else {
|
||||||
}
|
return " ";
|
||||||
} else {
|
}
|
||||||
if (this.down) {
|
|
||||||
if (this.left) {
|
|
||||||
if (this.right) {
|
|
||||||
return HORIZONTAL_DOWN;
|
|
||||||
} else {
|
|
||||||
return DOWN_LEFT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.right) {
|
|
||||||
return DOWN_RIGHT;
|
|
||||||
} else {
|
|
||||||
return DOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.left) {
|
|
||||||
if (this.right) {
|
|
||||||
return HORIZONTAL;
|
|
||||||
} else {
|
|
||||||
return LEFT;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (this.right) {
|
|
||||||
return RIGHT;
|
|
||||||
} else {
|
|
||||||
return " ";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package ch.fritteli.labyrinth;
|
package ch.fritteli.labyrinth;
|
||||||
|
|
||||||
import ch.fritteli.labyrinth.TextRenderer.CharDefinition;
|
import ch.fritteli.labyrinth.TextRenderer.Generator.CharDefinition;
|
||||||
import org.junit.jupiter.api.Nested;
|
import org.junit.jupiter.api.Nested;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue