Enable showing/rendering the solution.
This commit is contained in:
parent
0a655bd617
commit
c6b8b0e3bd
4 changed files with 83 additions and 23 deletions
|
@ -1,9 +1,36 @@
|
||||||
package ch.fritteli.labyrinth;
|
package ch.fritteli.labyrinth;
|
||||||
|
|
||||||
|
import io.vavr.collection.HashSet;
|
||||||
|
import io.vavr.collection.Set;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
|
||||||
public class HTMLRenderer {
|
public class HTMLRenderer {
|
||||||
private static final String PREAMBLE = "<!DOCTYPE html><html><head><title>Labyrinth</title><style>table{border-collapse:collapse;}td{border:0 solid black;height:1em;width:1em;}td.top{border-top-width:1px;}td.right{border-right-width:1px;}td.bottom{border-bottom-width:1px;}td.left{border-left-width:1px;}</style></head><body>";
|
private static final String PREAMBLE = "<!DOCTYPE html><html lang=\"en\">" +
|
||||||
|
"<head>" +
|
||||||
|
"<title>Labyrinth</title>" +
|
||||||
|
"<style>" +
|
||||||
|
"table{border-collapse:collapse;}" +
|
||||||
|
"td{border:0 solid black;height:1em;width:1em;}" +
|
||||||
|
"td.top{border-top-width:1px;}" +
|
||||||
|
"td.right{border-right-width:1px;}" +
|
||||||
|
"td.bottom{border-bottom-width:1px;}" +
|
||||||
|
"td.left{border-left-width:1px;}" +
|
||||||
|
"</style>" +
|
||||||
|
"<script>" +
|
||||||
|
"let solution = false;" +
|
||||||
|
"function toggleSolution() {" +
|
||||||
|
"let stylesheet = document.styleSheets[0];" +
|
||||||
|
"if(solution){" +
|
||||||
|
"stylesheet.deleteRule(0);" +
|
||||||
|
"}else{" +
|
||||||
|
"stylesheet.insertRule(\"td.solution{background-color:lightgray;}\", 0);" +
|
||||||
|
"}" +
|
||||||
|
"solution = !solution;" +
|
||||||
|
"}" +
|
||||||
|
"</script>" +
|
||||||
|
"</head>" +
|
||||||
|
"<body>" +
|
||||||
|
"<input type=\"checkbox\" onclick=\"toggleSolution()\">show solution</input>";
|
||||||
private static final String POSTAMBLE = "</body></html>";
|
private static final String POSTAMBLE = "</body></html>";
|
||||||
private final Labyrinth labyrinth;
|
private final Labyrinth labyrinth;
|
||||||
private final int width;
|
private final int width;
|
||||||
|
@ -44,22 +71,31 @@ public class HTMLRenderer {
|
||||||
for (int x = 0; x < this.width; x++) {
|
for (int x = 0; x < this.width; x++) {
|
||||||
final Tile currentTile = this.labyrinth.getTileAt(x, this.y);
|
final Tile currentTile = this.labyrinth.getTileAt(x, this.y);
|
||||||
sb.append("<td class=\"");
|
sb.append("<td class=\"");
|
||||||
if (currentTile.hasWallAt(Direction.TOP)) {
|
sb.append(this.getClasses(currentTile).mkString(" "));
|
||||||
sb.append("top ");
|
|
||||||
}
|
|
||||||
if (currentTile.hasWallAt(Direction.RIGHT)) {
|
|
||||||
sb.append("right ");
|
|
||||||
}
|
|
||||||
if (currentTile.hasWallAt(Direction.BOTTOM)) {
|
|
||||||
sb.append("bottom ");
|
|
||||||
}
|
|
||||||
if (currentTile.hasWallAt(Direction.LEFT)) {
|
|
||||||
sb.append("left ");
|
|
||||||
}
|
|
||||||
sb.append("\"> </td>");
|
sb.append("\"> </td>");
|
||||||
}
|
}
|
||||||
sb.append("</tr>");
|
sb.append("</tr>");
|
||||||
this.y++;
|
this.y++;
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,15 @@ public class Labyrinth {
|
||||||
private final int width;
|
private final int width;
|
||||||
@Getter
|
@Getter
|
||||||
private final int height;
|
private final int height;
|
||||||
|
private final Position start;
|
||||||
|
private final Position end;
|
||||||
|
|
||||||
public Labyrinth(final int width, final int height) {
|
public Labyrinth(final int width, final int height) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.field = new Tile[width][height];
|
this.field = new Tile[width][height];
|
||||||
|
this.start = new Position(0, 0);
|
||||||
|
this.end = new Position(this.width - 1, this.height - 1);
|
||||||
this.initField();
|
this.initField();
|
||||||
this.generate();
|
this.generate();
|
||||||
}
|
}
|
||||||
|
@ -30,6 +34,14 @@ public class Labyrinth {
|
||||||
return this.field[x][y];
|
return this.field[x][y];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tile getStartTile() {
|
||||||
|
return this.getTileAt(this.start);
|
||||||
|
}
|
||||||
|
|
||||||
|
Tile getEndTile() {
|
||||||
|
return this.getTileAt(this.end);
|
||||||
|
}
|
||||||
|
|
||||||
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];
|
||||||
|
@ -70,11 +82,10 @@ public class Labyrinth {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void preDig() {
|
private void preDig() {
|
||||||
final Position bottomRight = new Position(Labyrinth.this.width - 1, Labyrinth.this.height - 1);
|
final Tile endTile = Labyrinth.this.getEndTile();
|
||||||
final Tile bottomRightTile = Labyrinth.this.getTileAt(bottomRight);
|
endTile.enableDiggingToOrFrom(Direction.BOTTOM);
|
||||||
bottomRightTile.enableDiggingToOrFrom(Direction.BOTTOM);
|
endTile.digFrom(Direction.BOTTOM);
|
||||||
bottomRightTile.digFrom(Direction.BOTTOM);
|
this.positions.push(Labyrinth.this.end);
|
||||||
this.positions.push(bottomRight);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void dig() {
|
private void dig() {
|
||||||
|
@ -90,6 +101,9 @@ public class Labyrinth {
|
||||||
if (currentTile.digTo(digTo) && neighborTile.digFrom(digFrom)) {
|
if (currentTile.digTo(digTo) && neighborTile.digFrom(digFrom)) {
|
||||||
// all ok!
|
// all ok!
|
||||||
this.positions.push(neighborPosition);
|
this.positions.push(neighborPosition);
|
||||||
|
if (neighborPosition.equals(Labyrinth.this.start)) {
|
||||||
|
this.markSolution();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// Hm, didn't work.
|
// Hm, didn't work.
|
||||||
currentTile.undigTo(digTo);
|
currentTile.undigTo(digTo);
|
||||||
|
@ -101,11 +115,14 @@ public class Labyrinth {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void markSolution() {
|
||||||
|
this.positions.forEach(position -> Labyrinth.this.getTileAt(position).setSolution());
|
||||||
|
}
|
||||||
|
|
||||||
private void postDig() {
|
private void postDig() {
|
||||||
final Position topLeft = new Position(0, 0);
|
final Tile startTile = Labyrinth.this.getStartTile();
|
||||||
final Tile topLeftTile = Labyrinth.this.getTileAt(topLeft);
|
startTile.enableDiggingToOrFrom(Direction.TOP);
|
||||||
topLeftTile.enableDiggingToOrFrom(Direction.TOP);
|
startTile.digTo(Direction.TOP);
|
||||||
topLeftTile.digTo(Direction.TOP);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,7 +141,7 @@ public class TextRenderer {
|
||||||
charDef2.vertical();
|
charDef2.vertical();
|
||||||
}
|
}
|
||||||
|
|
||||||
result = charDef1 + " ";
|
result = charDef1 + (currentTile.isSolution() ? "x" : " ");
|
||||||
|
|
||||||
if (this.x == this.width - 1) {
|
if (this.x == this.width - 1) {
|
||||||
result += charDef2 + "\n";
|
result += charDef2 + "\n";
|
||||||
|
|
|
@ -3,6 +3,7 @@ package ch.fritteli.labyrinth;
|
||||||
import io.vavr.collection.Stream;
|
import io.vavr.collection.Stream;
|
||||||
import io.vavr.control.Option;
|
import io.vavr.control.Option;
|
||||||
import lombok.AccessLevel;
|
import lombok.AccessLevel;
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.experimental.FieldDefaults;
|
import lombok.experimental.FieldDefaults;
|
||||||
|
|
||||||
|
@ -10,6 +11,8 @@ import lombok.experimental.FieldDefaults;
|
||||||
public class Tile {
|
public class Tile {
|
||||||
final Walls walls = new Walls();
|
final Walls walls = new Walls();
|
||||||
boolean visited = false;
|
boolean visited = false;
|
||||||
|
@Getter
|
||||||
|
boolean solution = false;
|
||||||
|
|
||||||
public Tile() {
|
public Tile() {
|
||||||
this.walls.setAll();
|
this.walls.setAll();
|
||||||
|
@ -46,4 +49,8 @@ public class Tile {
|
||||||
public boolean hasWallAt(@NonNull final Direction direction) {
|
public boolean hasWallAt(@NonNull final Direction direction) {
|
||||||
return this.walls.isSet(direction);
|
return this.walls.isSet(direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSolution() {
|
||||||
|
this.solution = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue