Refactor the PDFRenderer
This commit is contained in:
		
							parent
							
								
									66ddb27291
								
							
						
					
					
						commit
						0bdbd7d0ef
					
				
					 1 changed files with 194 additions and 198 deletions
				
			
		|  | @ -1,6 +1,7 @@ | ||||||
| package ch.fritteli.labyrinth; | package ch.fritteli.labyrinth; | ||||||
| 
 | 
 | ||||||
| import lombok.NonNull; | import lombok.NonNull; | ||||||
|  | import lombok.RequiredArgsConstructor; | ||||||
| import lombok.Value; | import lombok.Value; | ||||||
| import org.apache.pdfbox.pdmodel.PDDocument; | import org.apache.pdfbox.pdmodel.PDDocument; | ||||||
| import org.apache.pdfbox.pdmodel.PDDocumentInformation; | import org.apache.pdfbox.pdmodel.PDDocumentInformation; | ||||||
|  | @ -26,63 +27,104 @@ public class PDFRenderer implements Renderer<byte[]> { | ||||||
|         return new PDFRenderer(); |         return new PDFRenderer(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private static boolean isValid(@NonNull final Position position) { |  | ||||||
|         return position.getX() >= 0 && position.getY() >= 0; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |     @Override | ||||||
|     @NonNull |     @NonNull | ||||||
|     public byte[] render(@NonNull final Labyrinth labyrinth) { |     public byte[] render(@NonNull final Labyrinth labyrinth) { | ||||||
|         final float pageWidth = labyrinth.getWidth() * SCALE + 2 * MARGIN; |         final Generator generator = new Generator(labyrinth); | ||||||
|         final float pageHeight = labyrinth.getHeight() * SCALE + 2 * MARGIN; |         return generator.generate(); | ||||||
| 
 |  | ||||||
|         final PDDocument pdDocument = new PDDocument(); |  | ||||||
|         final PDDocumentInformation info = new PDDocumentInformation(); |  | ||||||
|         info.setTitle("Labyrinth " + labyrinth.getWidth() + "x" + labyrinth.getHeight() + ", ID " + labyrinth.getRandomSeed()); |  | ||||||
|         pdDocument.setDocumentInformation(info); |  | ||||||
|         final PDPage page = new PDPage(new PDRectangle(pageWidth, pageHeight)); |  | ||||||
|         final PDPage solution = new PDPage(new PDRectangle(pageWidth, pageHeight)); |  | ||||||
|         pdDocument.addPage(page); |  | ||||||
|         pdDocument.addPage(solution); |  | ||||||
|         try (final PDPageContentStream labyrinthPageContentStream = new PDPageContentStream(pdDocument, page); |  | ||||||
|              final PDPageContentStream solutionPageContentStream = new PDPageContentStream(pdDocument, solution)) { |  | ||||||
|             setUpPageContentStream(labyrinthPageContentStream); |  | ||||||
|             setUpPageContentStream(solutionPageContentStream); |  | ||||||
|             this.drawHorizonzalLines(labyrinth, labyrinthPageContentStream, solutionPageContentStream); |  | ||||||
|             this.drawVerticalLines(labyrinth, labyrinthPageContentStream, solutionPageContentStream); |  | ||||||
|             this.drawSolution(labyrinth, solutionPageContentStream); |  | ||||||
|         } catch (IOException e) { |  | ||||||
|             e.printStackTrace(); |  | ||||||
|         } |  | ||||||
|         final ByteArrayOutputStream output = new ByteArrayOutputStream(); |  | ||||||
|         try { |  | ||||||
|             pdDocument.save(output); |  | ||||||
|             pdDocument.close(); |  | ||||||
|         } catch (IOException e) { |  | ||||||
|             e.printStackTrace(); |  | ||||||
|         } |  | ||||||
|         return output.toByteArray(); |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void setUpPageContentStream(@NonNull final PDPageContentStream pageContentStream) throws IOException { |  | ||||||
|         pageContentStream.setLineCapStyle(BasicStroke.CAP_ROUND); |  | ||||||
|         pageContentStream.setLineJoinStyle(BasicStroke.JOIN_ROUND); |  | ||||||
|         pageContentStream.setLineWidth(1.0f); |  | ||||||
|         pageContentStream.setStrokingColor(Color.BLACK); |  | ||||||
|         pageContentStream.setNonStrokingColor(Color.BLACK); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     private void drawHorizonzalLines(@NonNull final Labyrinth labyrinth, |     @RequiredArgsConstructor | ||||||
|                                      @NonNull final PDPageContentStream... contentStreams) throws IOException { |     private static class Generator { | ||||||
|         // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required. |         @NonNull | ||||||
|         Coordinate coordinate = new Coordinate(0f, 0f); |         private final Labyrinth labyrinth; | ||||||
|         for (int y = 0; y < labyrinth.getHeight(); y++) { | 
 | ||||||
|  |         private static boolean isValid(@NonNull final Position position) { | ||||||
|  |             return position.getX() >= 0 && position.getY() >= 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         public byte[] generate() { | ||||||
|  |             final float pageWidth = this.labyrinth.getWidth() * SCALE + 2 * MARGIN; | ||||||
|  |             final float pageHeight = this.labyrinth.getHeight() * SCALE + 2 * MARGIN; | ||||||
|  | 
 | ||||||
|  |             final PDDocument pdDocument = new PDDocument(); | ||||||
|  |             final PDDocumentInformation info = new PDDocumentInformation(); | ||||||
|  |             info.setTitle("Labyrinth " + this.labyrinth.getWidth() + "x" + this.labyrinth.getHeight() + ", ID " + this.labyrinth.getRandomSeed()); | ||||||
|  |             pdDocument.setDocumentInformation(info); | ||||||
|  |             final PDPage page = new PDPage(new PDRectangle(pageWidth, pageHeight)); | ||||||
|  |             final PDPage solution = new PDPage(new PDRectangle(pageWidth, pageHeight)); | ||||||
|  |             pdDocument.addPage(page); | ||||||
|  |             pdDocument.addPage(solution); | ||||||
|  |             try (final PDPageContentStream labyrinthPageContentStream = new PDPageContentStream(pdDocument, page); | ||||||
|  |                  final PDPageContentStream solutionPageContentStream = new PDPageContentStream(pdDocument, solution)) { | ||||||
|  |                 setUpPageContentStream(labyrinthPageContentStream); | ||||||
|  |                 setUpPageContentStream(solutionPageContentStream); | ||||||
|  |                 this.drawHorizonzalLines(labyrinthPageContentStream, solutionPageContentStream); | ||||||
|  |                 this.drawVerticalLines(labyrinthPageContentStream, solutionPageContentStream); | ||||||
|  |                 this.drawSolution(solutionPageContentStream); | ||||||
|  |             } catch (IOException e) { | ||||||
|  |                 e.printStackTrace(); | ||||||
|  |             } | ||||||
|  |             final ByteArrayOutputStream output = new ByteArrayOutputStream(); | ||||||
|  |             try { | ||||||
|  |                 pdDocument.save(output); | ||||||
|  |                 pdDocument.close(); | ||||||
|  |             } catch (IOException e) { | ||||||
|  |                 e.printStackTrace(); | ||||||
|  |             } | ||||||
|  |             return output.toByteArray(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void setUpPageContentStream(@NonNull final PDPageContentStream pageContentStream) throws IOException { | ||||||
|  |             pageContentStream.setLineCapStyle(BasicStroke.CAP_ROUND); | ||||||
|  |             pageContentStream.setLineJoinStyle(BasicStroke.JOIN_ROUND); | ||||||
|  |             pageContentStream.setLineWidth(1.0f); | ||||||
|  |             pageContentStream.setStrokingColor(Color.BLACK); | ||||||
|  |             pageContentStream.setNonStrokingColor(Color.BLACK); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         private void drawHorizonzalLines(@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. | ||||||
|  |             Coordinate coordinate = new Coordinate(0f, 0f); | ||||||
|  |             for (int y = 0; y < this.labyrinth.getHeight(); y++) { | ||||||
|  |                 boolean isPainting = false; | ||||||
|  |                 coordinate = coordinate.withY(y); | ||||||
|  |                 for (int x = 0; x < this.labyrinth.getWidth(); x++) { | ||||||
|  |                     final Tile currentTile = this.labyrinth.getTileAt(x, y); | ||||||
|  |                     coordinate = coordinate.withX(x); | ||||||
|  |                     if (currentTile.hasWallAt(Direction.TOP)) { | ||||||
|  |                         if (!isPainting) { | ||||||
|  |                             for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|  |                                 contentStream.moveTo(coordinate.getX(), coordinate.getY()); | ||||||
|  |                             } | ||||||
|  |                             isPainting = true; | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         if (isPainting) { | ||||||
|  |                             for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|  |                                 contentStream.lineTo(coordinate.getX(), coordinate.getY()); | ||||||
|  |                                 contentStream.stroke(); | ||||||
|  |                             } | ||||||
|  |                             isPainting = false; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 if (isPainting) { | ||||||
|  |                     coordinate = coordinate.withX(this.labyrinth.getWidth()); | ||||||
|  |                     for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|  |                         contentStream.lineTo(coordinate.getX(), coordinate.getY()); | ||||||
|  |                         contentStream.stroke(); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|             boolean isPainting = false; |             boolean isPainting = false; | ||||||
|             coordinate = coordinate.withY(y, labyrinth); |             int y = this.labyrinth.getHeight(); | ||||||
|             for (int x = 0; x < labyrinth.getWidth(); x++) { |             coordinate = coordinate.withY(this.labyrinth.getHeight()); | ||||||
|                 final Tile currentTile = labyrinth.getTileAt(x, y); |             for (int x = 0; x < this.labyrinth.getWidth(); x++) { | ||||||
|  |                 final Tile currentTile = this.labyrinth.getTileAt(x, y - 1); | ||||||
|                 coordinate = coordinate.withX(x); |                 coordinate = coordinate.withX(x); | ||||||
|                 if (currentTile.hasWallAt(Direction.TOP)) { |                 if (currentTile.hasWallAt(Direction.BOTTOM)) { | ||||||
|                     if (!isPainting) { |                     if (!isPainting) { | ||||||
|                         for (final PDPageContentStream contentStream : contentStreams) { |                         for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|                             contentStream.moveTo(coordinate.getX(), coordinate.getY()); |                             contentStream.moveTo(coordinate.getX(), coordinate.getY()); | ||||||
|  | @ -100,57 +142,55 @@ public class PDFRenderer implements Renderer<byte[]> { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (isPainting) { |             if (isPainting) { | ||||||
|                 coordinate = coordinate.withX(labyrinth.getWidth()); |                 coordinate = coordinate.withX(this.labyrinth.getWidth()); | ||||||
|                 for (final PDPageContentStream contentStream : contentStreams) { |                 for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|                     contentStream.lineTo(coordinate.getX(), coordinate.getY()); |                     contentStream.lineTo(coordinate.getX(), coordinate.getY()); | ||||||
|                     contentStream.stroke(); |                     contentStream.stroke(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         boolean isPainting = false; | 
 | ||||||
|         int y = labyrinth.getHeight(); |         private void drawVerticalLines(@NonNull final PDPageContentStream... contentStreams) throws IOException { | ||||||
|         coordinate = coordinate.withY(labyrinth.getHeight(), labyrinth); |             // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required. | ||||||
|         for (int x = 0; x < labyrinth.getWidth(); x++) { |             Coordinate coordinate = new Coordinate(0f, 0f); | ||||||
|             final Tile currentTile = labyrinth.getTileAt(x, y - 1); |             for (int x = 0; x < this.labyrinth.getWidth(); x++) { | ||||||
|             coordinate = coordinate.withX(x); |                 boolean isPainting = false; | ||||||
|             if (currentTile.hasWallAt(Direction.BOTTOM)) { |                 coordinate = coordinate.withX(x); | ||||||
|                 if (!isPainting) { |                 for (int y = 0; y < this.labyrinth.getHeight(); y++) { | ||||||
|                     for (final PDPageContentStream contentStream : contentStreams) { |                     final Tile currentTile = this.labyrinth.getTileAt(x, y); | ||||||
|                         contentStream.moveTo(coordinate.getX(), coordinate.getY()); |                     coordinate = coordinate.withY(y); | ||||||
|  |                     if (currentTile.hasWallAt(Direction.LEFT)) { | ||||||
|  |                         if (!isPainting) { | ||||||
|  |                             for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|  |                                 contentStream.moveTo(coordinate.getX(), coordinate.getY()); | ||||||
|  |                             } | ||||||
|  |                             isPainting = true; | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         if (isPainting) { | ||||||
|  |                             for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|  |                                 contentStream.lineTo(coordinate.getX(), coordinate.getY()); | ||||||
|  |                                 contentStream.stroke(); | ||||||
|  |                             } | ||||||
|  |                             isPainting = false; | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                     isPainting = true; |  | ||||||
|                 } |                 } | ||||||
|             } else { |  | ||||||
|                 if (isPainting) { |                 if (isPainting) { | ||||||
|  |                     coordinate = coordinate.withY(this.labyrinth.getHeight()); | ||||||
|                     for (final PDPageContentStream contentStream : contentStreams) { |                     for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|                         contentStream.lineTo(coordinate.getX(), coordinate.getY()); |                         contentStream.lineTo(coordinate.getX(), coordinate.getY()); | ||||||
|                         contentStream.stroke(); |                         contentStream.stroke(); | ||||||
|                     } |                     } | ||||||
|                     isPainting = false; |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |  | ||||||
|         if (isPainting) { |  | ||||||
|             coordinate = coordinate.withX(labyrinth.getWidth()); |  | ||||||
|             for (final PDPageContentStream contentStream : contentStreams) { |  | ||||||
|                 contentStream.lineTo(coordinate.getX(), coordinate.getY()); |  | ||||||
|                 contentStream.stroke(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private void drawVerticalLines(@NonNull final Labyrinth labyrinth, |  | ||||||
|                                    @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. |  | ||||||
|         Coordinate coordinate = new Coordinate(0f, 0f); |  | ||||||
|         final float labyrinthHeight = labyrinth.getHeight() * SCALE; |  | ||||||
|         for (int x = 0; x < labyrinth.getWidth(); x++) { |  | ||||||
|             boolean isPainting = false; |             boolean isPainting = false; | ||||||
|             coordinate = coordinate.withX(x); |             int x = this.labyrinth.getWidth(); | ||||||
|             for (int y = 0; y < labyrinth.getHeight(); y++) { |             coordinate = coordinate.withX(this.labyrinth.getWidth()); | ||||||
|                 final Tile currentTile = labyrinth.getTileAt(x, y); |             for (int y = 0; y < this.labyrinth.getHeight(); y++) { | ||||||
|                 coordinate = coordinate.withY(y, labyrinth); |                 final Tile currentTile = this.labyrinth.getTileAt(x - 1, y); | ||||||
|                 if (currentTile.hasWallAt(Direction.LEFT)) { |                 coordinate = coordinate.withY(y); | ||||||
|  |                 if (currentTile.hasWallAt(Direction.RIGHT)) { | ||||||
|                     if (!isPainting) { |                     if (!isPainting) { | ||||||
|                         for (final PDPageContentStream contentStream : contentStreams) { |                         for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|                             contentStream.moveTo(coordinate.getX(), coordinate.getY()); |                             contentStream.moveTo(coordinate.getX(), coordinate.getY()); | ||||||
|  | @ -168,138 +208,94 @@ public class PDFRenderer implements Renderer<byte[]> { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (isPainting) { |             if (isPainting) { | ||||||
|                 coordinate = coordinate.withY(labyrinth.getHeight(), labyrinth); |                 coordinate = coordinate.withY(this.labyrinth.getHeight()); | ||||||
|                 for (final PDPageContentStream contentStream : contentStreams) { |                 for (final PDPageContentStream contentStream : contentStreams) { | ||||||
|                     contentStream.lineTo(coordinate.getX(), coordinate.getY()); |                     contentStream.lineTo(coordinate.getX(), coordinate.getY()); | ||||||
|                     contentStream.stroke(); |                     contentStream.stroke(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         boolean isPainting = false; | 
 | ||||||
|         int x = labyrinth.getWidth(); |         private void drawSolution(@NonNull final PDPageContentStream pageContentStream) throws IOException { | ||||||
|         coordinate = coordinate.withX(labyrinth.getWidth()); |             // Draw the solution in red | ||||||
|         for (int y = 0; y < labyrinth.getHeight(); y++) { |             pageContentStream.setStrokingColor(Color.RED); | ||||||
|             final Tile currentTile = labyrinth.getTileAt(x - 1, y); |             // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required. | ||||||
|             coordinate = coordinate.withY(y, labyrinth); |             final Position end = this.labyrinth.getEnd(); | ||||||
|             if (currentTile.hasWallAt(Direction.RIGHT)) { |             Position currentPosition = this.labyrinth.getStart(); | ||||||
|                 if (!isPainting) { |             Position previousPosition = null; | ||||||
|                     for (final PDPageContentStream contentStream : contentStreams) { |             SolutionCoordinate coordinate = new SolutionCoordinate(currentPosition.getX(), currentPosition.getY()); | ||||||
|                         contentStream.moveTo(coordinate.getX(), coordinate.getY()); |             pageContentStream.moveTo(coordinate.getX(), coordinate.getY()); | ||||||
|  |             do { | ||||||
|  |                 Position newCurrent = this.findNextSolutionPosition(previousPosition, currentPosition); | ||||||
|  |                 previousPosition = currentPosition; | ||||||
|  |                 currentPosition = newCurrent; | ||||||
|  |                 coordinate = new SolutionCoordinate(currentPosition.getX(), currentPosition.getY()); | ||||||
|  |                 pageContentStream.lineTo(coordinate.getX(), coordinate.getY()); | ||||||
|  |             } while (!currentPosition.equals(end)); | ||||||
|  |             pageContentStream.stroke(); | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         @NonNull | ||||||
|  |         private Position findNextSolutionPosition(@Nullable final Position previousPosition, @NonNull final Position currentPosition) { | ||||||
|  |             final Tile currentTile = this.labyrinth.getTileAt(currentPosition); | ||||||
|  |             for (final Direction direction : Direction.values()) { | ||||||
|  |                 if (!currentTile.hasWallAt(direction)) { | ||||||
|  |                     final Position position = direction.translate(currentPosition); | ||||||
|  |                     if (position.equals(previousPosition) || !isValid(position)) { | ||||||
|  |                         continue; | ||||||
|                     } |                     } | ||||||
|                     isPainting = true; |                     if (this.labyrinth.getTileAt(position).isSolution()) { | ||||||
|                 } |                         return position; | ||||||
|             } else { |  | ||||||
|                 if (isPainting) { |  | ||||||
|                     for (final PDPageContentStream contentStream : contentStreams) { |  | ||||||
|                         contentStream.lineTo(coordinate.getX(), coordinate.getY()); |  | ||||||
|                         contentStream.stroke(); |  | ||||||
|                     } |                     } | ||||||
|                     isPainting = false; |  | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |             throw new IllegalStateException("We *SHOULD* never have gotten here. ... famous last words ..."); | ||||||
|         } |         } | ||||||
|         if (isPainting) { | 
 | ||||||
|             coordinate = coordinate.withY(labyrinth.getHeight(), labyrinth); |         @Value | ||||||
|             for (final PDPageContentStream contentStream : contentStreams) { |         private class Coordinate { | ||||||
|                 contentStream.lineTo(coordinate.getX(), coordinate.getY()); |             float x; | ||||||
|                 contentStream.stroke(); |             float y; | ||||||
|  | 
 | ||||||
|  |             public Coordinate(final float x, final float y) { | ||||||
|  |                 this.x = x; | ||||||
|  |                 this.y = y; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             private float calcX(final int x) { | ||||||
|  |                 return x * SCALE + MARGIN; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             private float calcY(final int y) { | ||||||
|  |                 return (Generator.this.labyrinth.getHeight() - y) * SCALE + MARGIN; | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             public Coordinate withX(final int x) { | ||||||
|  |                 return new Coordinate(calcX(x), this.y); | ||||||
|  |             } | ||||||
|  | 
 | ||||||
|  |             public Coordinate withY(final int y) { | ||||||
|  |                 return new Coordinate(this.x, calcY(y)); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     private void drawSolution(@NonNull final Labyrinth labyrinth, |         @Value | ||||||
|                               @NonNull final PDPageContentStream pageContentStream) throws IOException { |         private class SolutionCoordinate { | ||||||
|         // Draw the solution in red |             float x; | ||||||
|         pageContentStream.setStrokingColor(Color.RED); |             float y; | ||||||
|         // PDF has the origin in the lower left corner. We want it in the upper left corner, hence some magic is required. |  | ||||||
|         final Position end = labyrinth.getEnd(); |  | ||||||
|         Position currentPosition = labyrinth.getStart(); |  | ||||||
|         Position previousPosition = null; |  | ||||||
|         SolutionCoordinate coordinate = new SolutionCoordinate(currentPosition.getX(), currentPosition.getY(), labyrinth); |  | ||||||
|         pageContentStream.moveTo(coordinate.getX(), coordinate.getY()); |  | ||||||
|         do { |  | ||||||
|             Position newCurrent = this.findNextSolutionPosition(labyrinth, previousPosition, currentPosition); |  | ||||||
|             previousPosition = currentPosition; |  | ||||||
|             currentPosition = newCurrent; |  | ||||||
|             coordinate = new SolutionCoordinate(currentPosition.getX(), currentPosition.getY(), labyrinth); |  | ||||||
|             pageContentStream.lineTo(coordinate.getX(), coordinate.getY()); |  | ||||||
|         } while (!currentPosition.equals(end)); |  | ||||||
|         pageContentStream.stroke(); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     @NonNull |             public SolutionCoordinate(final int x, final int y) { | ||||||
|     private Position findNextSolutionPosition(@NonNull final Labyrinth labyrinth, @Nullable final Position previousPosition, @NonNull final Position currentPosition) { |                 this.x = calcX(x); | ||||||
|         final Tile currentTile = labyrinth.getTileAt(currentPosition); |                 this.y = calcY(y); | ||||||
|         for (final Direction direction : Direction.values()) { |  | ||||||
|             if (!currentTile.hasWallAt(direction)) { |  | ||||||
|                 final Position position = direction.translate(currentPosition); |  | ||||||
|                 if (position.equals(previousPosition) || !isValid(position)) { |  | ||||||
|                     continue; |  | ||||||
|                 } |  | ||||||
|                 if (labyrinth.getTileAt(position).isSolution()) { |  | ||||||
|                     return position; |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         } |  | ||||||
|         throw new IllegalStateException("We *SHOULD* never have gotten here. ... famous last words ..."); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     @Value |             private float calcX(final int x) { | ||||||
|     private static class Coordinate { |                 return x * SCALE + SCALE / 2 + MARGIN; | ||||||
|         float x; |             } | ||||||
|         float y; |  | ||||||
| 
 | 
 | ||||||
|         public Coordinate(final float x, final float y) { |             private float calcY(final int y) { | ||||||
|             this.x = x; |                 return (Generator.this.labyrinth.getHeight() - y) * SCALE - SCALE / 2 + MARGIN; | ||||||
|             this.y = y; |             } | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private static float calcX(final int x) { |  | ||||||
|             return x * SCALE + MARGIN; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private static float calcY(final int y, @NonNull final Labyrinth labyrinth) { |  | ||||||
|             return (labyrinth.getHeight() - y) * SCALE + MARGIN; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public Coordinate withX(final int x) { |  | ||||||
|             return new Coordinate(calcX(x), this.y); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public Coordinate withY(final int y, @NonNull final Labyrinth labyrinth) { |  | ||||||
|             return new Coordinate(this.x, calcY(y, labyrinth)); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Value |  | ||||||
|     private static class SolutionCoordinate { |  | ||||||
|         float x; |  | ||||||
|         float y; |  | ||||||
| 
 |  | ||||||
|         public SolutionCoordinate(final float x, final float y) { |  | ||||||
|             this.x = x; |  | ||||||
|             this.y = y; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public SolutionCoordinate(final int x, final int y, @NonNull final Labyrinth labyrinth) { |  | ||||||
|             this.x = calcX(x); |  | ||||||
|             this.y = calcY(y, labyrinth); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private static float calcX(final int x) { |  | ||||||
|             return x * SCALE + SCALE / 2 + MARGIN; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         private static float calcY(final int y, @NonNull final Labyrinth labyrinth) { |  | ||||||
|             return (labyrinth.getHeight() - y) * SCALE - SCALE / 2 + MARGIN; |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public SolutionCoordinate withX(final int x) { |  | ||||||
|             return new SolutionCoordinate(calcX(x), this.y); |  | ||||||
|         } |  | ||||||
| 
 |  | ||||||
|         public SolutionCoordinate withY(final int y, @NonNull final Labyrinth labyrinth) { |  | ||||||
|             return new SolutionCoordinate(this.x, calcY(y, labyrinth)); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue