Split up config interface, main and actual frame
This commit is contained in:
		
							parent
							
								
									bc4f95a0a0
								
							
						
					
					
						commit
						bddaa19ca4
					
				
					 4 changed files with 311 additions and 259 deletions
				
			
		|  | @ -1,266 +1,18 @@ | |||
| package de.oshgnacknak.gruphi; | ||||
| 
 | ||||
| import h07.graph.DirectedGraph; | ||||
| import h07.graph.DirectedGraphFactory; | ||||
| 
 | ||||
| import javax.swing.*; | ||||
| import java.awt.*; | ||||
| import java.awt.event.KeyAdapter; | ||||
| import java.awt.event.KeyEvent; | ||||
| import java.awt.event.MouseAdapter; | ||||
| import java.awt.event.MouseEvent; | ||||
| import java.util.Optional; | ||||
| import java.util.function.BiPredicate; | ||||
| 
 | ||||
| class Gruphi extends JFrame { | ||||
| public interface Gruphi { | ||||
| 
 | ||||
|     private static final int FRAME_DELAY = 1000 / 60; | ||||
|     private static final double VEL = 5; | ||||
|     private static final double NEIGHBOUR_DISTANCE = 50; | ||||
|     long getFrameDelay(); | ||||
| 
 | ||||
|     private final DirectedGraph<Node, Double> graph; | ||||
|     double getVelocity(); | ||||
| 
 | ||||
|     private final MazeGenerator<Node> mazeGenerator; | ||||
|     double getGridSpacing(); | ||||
| 
 | ||||
|     private Node selected = null; | ||||
|     private final Vector vel = new Vector(0, 0); | ||||
|     private boolean running = true; | ||||
|     BiPredicate<Node, Node> getNeighbourPredicate(); | ||||
| 
 | ||||
|     Gruphi(DirectedGraphFactory<Node, Double> factory) { | ||||
|         super("Gruphi - The Graph GUI - By Osh"); | ||||
| 
 | ||||
|         this.graph = factory.createDirectedGraph(); | ||||
|         this. mazeGenerator = new MazeGenerator<>(graph, (a, b) -> | ||||
|             a.pos.dist(b.pos) <= NEIGHBOUR_DISTANCE); | ||||
| 
 | ||||
|         add(new Canvas(this::draw)); | ||||
|         pack(); | ||||
|         setLocationRelativeTo(null); | ||||
|         setDefaultCloseOperation(EXIT_ON_CLOSE); | ||||
| 
 | ||||
|         var mouseListener = new MouseAdapter() { | ||||
| 
 | ||||
|             @Override | ||||
|             public void mousePressed(MouseEvent e) { | ||||
|                 switch (e.getButton()) { | ||||
|                     case MouseEvent.BUTTON1: { | ||||
|                         if (selected != null) { | ||||
|                             var clicked = findClickedNode(e); | ||||
|                             if (clicked.isPresent()) { | ||||
|                                 var n = clicked.get(); | ||||
|                                 if (graph.getChildrenForNode(selected).contains(n)) { | ||||
|                                     graph.disconnectNodes(selected, n); | ||||
|                                 } else { | ||||
|                                     graph.connectNodes(selected, 1.0, n); | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 selected.pos.x = e.getX(); | ||||
|                                 selected.pos.y = e.getY(); | ||||
|                             } | ||||
|                         } else { | ||||
|                             graph.addNode(new Node(e.getX(), e.getY())); | ||||
|                         } | ||||
|                     } break; | ||||
| 
 | ||||
|                     case MouseEvent.BUTTON3: { | ||||
|                         if (selected != null) { | ||||
|                             selected.color = Node.COLOR; | ||||
|                             selected.radius = Node.RADIUS; | ||||
|                             selected = null; | ||||
|                         } | ||||
|                         findClickedNode(e) | ||||
|                             .ifPresent(n -> { | ||||
|                                 selected = n; | ||||
|                                 selected.radius *= 1.3; | ||||
|                                 selected.color = Color.RED; | ||||
|                             }); | ||||
|                     } break; | ||||
| 
 | ||||
|                     default: break; | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         addMouseListener(mouseListener); | ||||
|         addMouseMotionListener(mouseListener); | ||||
| 
 | ||||
|         addKeyListener(new KeyAdapter() { | ||||
|             @Override | ||||
|             public void keyPressed(KeyEvent e) { | ||||
|                 switch (e.getKeyCode()) { | ||||
|                     case KeyEvent.VK_K: | ||||
|                     case KeyEvent.VK_W: | ||||
|                     case KeyEvent.VK_UP: { | ||||
|                         vel.y = -VEL; | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_J: | ||||
|                     case KeyEvent.VK_S: | ||||
|                     case KeyEvent.VK_DOWN: { | ||||
|                         vel.y = VEL; | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_H: | ||||
|                     case KeyEvent.VK_A: | ||||
|                     case KeyEvent.VK_LEFT: { | ||||
|                         vel.x = -VEL; | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_L: | ||||
|                     case KeyEvent.VK_D: | ||||
|                     case KeyEvent.VK_RIGHT: { | ||||
|                         vel.x = VEL; | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_X: | ||||
|                     case KeyEvent.VK_DELETE: | ||||
|                     case KeyEvent.VK_BACK_SPACE: { | ||||
|                         if (selected != null) { | ||||
|                             graph.removeNode(selected); | ||||
|                             selected = null; | ||||
|                         } | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_Q: | ||||
|                     case KeyEvent.VK_ESCAPE: { | ||||
|                         running = false; | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_C: { | ||||
|                         clearGraph(); | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_M: { | ||||
|                         if (selected != null) { | ||||
|                             mazeGenerator.generate(selected); | ||||
|                         } | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_G: { | ||||
|                         generateGrid(); | ||||
|                     } break; | ||||
| 
 | ||||
|                     default: break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void keyReleased(KeyEvent e) { | ||||
|                 switch (e.getKeyCode()) { | ||||
|                     case KeyEvent.VK_K: | ||||
|                     case KeyEvent.VK_J: | ||||
|                     case KeyEvent.VK_W: | ||||
|                     case KeyEvent.VK_S: | ||||
|                     case KeyEvent.VK_DOWN: | ||||
|                     case KeyEvent.VK_UP: { | ||||
|                         vel.y = 0; | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_H: | ||||
|                     case KeyEvent.VK_L: | ||||
|                     case KeyEvent.VK_A: | ||||
|                     case KeyEvent.VK_D: | ||||
|                     case KeyEvent.VK_RIGHT: | ||||
|                     case KeyEvent.VK_LEFT: { | ||||
|                         vel.x = 0; | ||||
|                     } break; | ||||
| 
 | ||||
|                     default: break; | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private void generateGrid() { | ||||
|         clearGraph(); | ||||
| 
 | ||||
|         var dist = NEIGHBOUR_DISTANCE; | ||||
| 
 | ||||
|         var rows = getHeight() / dist - 1; | ||||
|         var cols = getWidth() / dist - 1; | ||||
| 
 | ||||
|         for (int x = 0; x < cols; x++) { | ||||
|             for (int y = 0; y < rows; y++) { | ||||
|                 var n = new Node((x + 0.5) * dist, (y + 0.5) * dist); | ||||
|                 graph.addNode(n); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void clearGraph() { | ||||
|         selected = null; | ||||
|         for (var node : graph.getAllNodes()) { | ||||
|             graph.removeNode(node); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private Optional<Node> findClickedNode(MouseEvent e) { | ||||
|         return graph.getAllNodes() | ||||
|             .stream() | ||||
|             .filter(n -> | ||||
|                 n.inside(e.getX(), e.getY())) | ||||
|             .findFirst(); | ||||
|     } | ||||
| 
 | ||||
|     private void draw(Drawable d) { | ||||
|         d.fill(Color.BLACK); | ||||
|         d.rect(0, 0, getWidth(), getHeight()); | ||||
| 
 | ||||
|         d.strokeWeight(1); | ||||
|         d.fill(Color.WHITE); | ||||
|         for (var node : graph.getAllNodes()) { | ||||
|             for (var child : graph.getChildrenForNode(node)) { | ||||
|                 d.line(node.pos.x, node.pos.y, child.pos.x, child.pos.y); | ||||
| 
 | ||||
|                 var v = child.pos | ||||
|                     .copy() | ||||
|                     .sub(node.pos); | ||||
|                 var r = 4; | ||||
|                 var p = v.copy() | ||||
|                     .setMag(v.mag() - child.radius - r) | ||||
|                     .add(node.pos); | ||||
| 
 | ||||
|                 d.rotated(v.angle(), p.x, p.y, () -> | ||||
|                     d.triangle( | ||||
|                         p.x+r, p.y, | ||||
|                         p.x-r, p.y-r, | ||||
|                         p.x-r, p.y+r)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for (var node : graph.getAllNodes()) { | ||||
|             d.fill(node.color); | ||||
|             d.ellipse(node.pos.x, node.pos.y, node.radius * 2, node.radius * 2); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void updateLoop() { | ||||
|         var last = System.currentTimeMillis(); | ||||
|         var acc = 0; | ||||
| 
 | ||||
|         while (running) { | ||||
|             while (acc > FRAME_DELAY) { | ||||
|                 update(); | ||||
|                 acc -= FRAME_DELAY; | ||||
|             } | ||||
|             repaint(); | ||||
| 
 | ||||
|             var current = System.currentTimeMillis(); | ||||
|             acc += current - last; | ||||
|             last = current; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void update() { | ||||
|         if (selected != null) { | ||||
|             selected.pos.add(vel); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         // TODO: | ||||
|         // var gruphi = new Gruphi(new SomeFactory<>()); | ||||
|         // gruphi.setVisible(true); | ||||
|         // gruphi.updateLoop(); | ||||
|         // System.exit(0); | ||||
|     } | ||||
|     DirectedGraphFactory<Node, Double> getDirectedGraphFactory(); | ||||
| } | ||||
|  |  | |||
							
								
								
									
										254
									
								
								src/main/java/de/oshgnacknak/gruphi/GruphiFrame.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								src/main/java/de/oshgnacknak/gruphi/GruphiFrame.java
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,254 @@ | |||
| package de.oshgnacknak.gruphi; | ||||
| 
 | ||||
| import h07.graph.DirectedGraph; | ||||
| 
 | ||||
| import javax.swing.*; | ||||
| import java.awt.*; | ||||
| import java.awt.event.KeyAdapter; | ||||
| import java.awt.event.KeyEvent; | ||||
| import java.awt.event.MouseAdapter; | ||||
| import java.awt.event.MouseEvent; | ||||
| import java.util.Optional; | ||||
| 
 | ||||
| class GruphiFrame extends JFrame { | ||||
| 
 | ||||
|     private final DirectedGraph<Node, Double> graph; | ||||
| 
 | ||||
|     private final MazeGenerator<Node> mazeGenerator; | ||||
|     private final Gruphi gruphi; | ||||
| 
 | ||||
|     private Node selected = null; | ||||
|     private final Vector vel = new Vector(0, 0); | ||||
|     private boolean running = true; | ||||
| 
 | ||||
|     GruphiFrame(Gruphi gruphi) { | ||||
|         super("Gruphi - The Graph GUI - By Osh"); | ||||
| 
 | ||||
|         this.gruphi = gruphi; | ||||
|         this.graph = gruphi.getDirectedGraphFactory().createDirectedGraph(); | ||||
|         this.mazeGenerator = new MazeGenerator<>(graph, gruphi.getNeighbourPredicate()); | ||||
| 
 | ||||
|         add(new Canvas(this::draw)); | ||||
|         pack(); | ||||
|         setLocationRelativeTo(null); | ||||
|         setDefaultCloseOperation(EXIT_ON_CLOSE); | ||||
| 
 | ||||
|         var mouseListener = new MouseAdapter() { | ||||
| 
 | ||||
|             @Override | ||||
|             public void mousePressed(MouseEvent e) { | ||||
|                 switch (e.getButton()) { | ||||
|                     case MouseEvent.BUTTON1: { | ||||
|                         if (selected != null) { | ||||
|                             var clicked = findClickedNode(e); | ||||
|                             if (clicked.isPresent()) { | ||||
|                                 var n = clicked.get(); | ||||
|                                 if (graph.getChildrenForNode(selected).contains(n)) { | ||||
|                                     graph.disconnectNodes(selected, n); | ||||
|                                 } else { | ||||
|                                     graph.connectNodes(selected, 1.0, n); | ||||
|                                 } | ||||
|                             } else { | ||||
|                                 selected.pos.x = e.getX(); | ||||
|                                 selected.pos.y = e.getY(); | ||||
|                             } | ||||
|                         } else { | ||||
|                             graph.addNode(new Node(e.getX(), e.getY())); | ||||
|                         } | ||||
|                     } break; | ||||
| 
 | ||||
|                     case MouseEvent.BUTTON3: { | ||||
|                         if (selected != null) { | ||||
|                             selected.color = Node.COLOR; | ||||
|                             selected.radius = Node.RADIUS; | ||||
|                             selected = null; | ||||
|                         } | ||||
|                         findClickedNode(e) | ||||
|                             .ifPresent(n -> { | ||||
|                                 selected = n; | ||||
|                                 selected.radius *= 1.3; | ||||
|                                 selected.color = Color.RED; | ||||
|                             }); | ||||
|                     } break; | ||||
| 
 | ||||
|                     default: break; | ||||
|                 } | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         addMouseListener(mouseListener); | ||||
|         addMouseMotionListener(mouseListener); | ||||
| 
 | ||||
|         addKeyListener(new KeyAdapter() { | ||||
|             @Override | ||||
|             public void keyPressed(KeyEvent e) { | ||||
|                 switch (e.getKeyCode()) { | ||||
|                     case KeyEvent.VK_K: | ||||
|                     case KeyEvent.VK_W: | ||||
|                     case KeyEvent.VK_UP: { | ||||
|                         vel.y = -gruphi.getVelocity(); | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_J: | ||||
|                     case KeyEvent.VK_S: | ||||
|                     case KeyEvent.VK_DOWN: { | ||||
|                         vel.y = gruphi.getVelocity(); | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_H: | ||||
|                     case KeyEvent.VK_A: | ||||
|                     case KeyEvent.VK_LEFT: { | ||||
|                         vel.x = -gruphi.getVelocity(); | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_L: | ||||
|                     case KeyEvent.VK_D: | ||||
|                     case KeyEvent.VK_RIGHT: { | ||||
|                         vel.x = gruphi.getVelocity(); | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_X: | ||||
|                     case KeyEvent.VK_DELETE: | ||||
|                     case KeyEvent.VK_BACK_SPACE: { | ||||
|                         if (selected != null) { | ||||
|                             graph.removeNode(selected); | ||||
|                             selected = null; | ||||
|                         } | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_Q: | ||||
|                     case KeyEvent.VK_ESCAPE: { | ||||
|                         running = false; | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_C: { | ||||
|                         clearGraph(); | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_M: { | ||||
|                         if (selected != null) { | ||||
|                             mazeGenerator.generate(selected); | ||||
|                         } | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_G: { | ||||
|                         generateGrid(); | ||||
|                     } break; | ||||
| 
 | ||||
|                     default: break; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public void keyReleased(KeyEvent e) { | ||||
|                 switch (e.getKeyCode()) { | ||||
|                     case KeyEvent.VK_K: | ||||
|                     case KeyEvent.VK_J: | ||||
|                     case KeyEvent.VK_W: | ||||
|                     case KeyEvent.VK_S: | ||||
|                     case KeyEvent.VK_DOWN: | ||||
|                     case KeyEvent.VK_UP: { | ||||
|                         vel.y = 0; | ||||
|                     } break; | ||||
| 
 | ||||
|                     case KeyEvent.VK_H: | ||||
|                     case KeyEvent.VK_L: | ||||
|                     case KeyEvent.VK_A: | ||||
|                     case KeyEvent.VK_D: | ||||
|                     case KeyEvent.VK_RIGHT: | ||||
|                     case KeyEvent.VK_LEFT: { | ||||
|                         vel.x = 0; | ||||
|                     } break; | ||||
| 
 | ||||
|                     default: break; | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     private void generateGrid() { | ||||
|         clearGraph(); | ||||
| 
 | ||||
|         var dist = gruphi.getGridSpacing(); | ||||
| 
 | ||||
|         var rows = getHeight() / dist - 1; | ||||
|         var cols = getWidth() / dist - 1; | ||||
| 
 | ||||
|         for (int x = 0; x < cols; x++) { | ||||
|             for (int y = 0; y < rows; y++) { | ||||
|                 var n = new Node((x + 0.5) * dist, (y + 0.5) * dist); | ||||
|                 graph.addNode(n); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void clearGraph() { | ||||
|         selected = null; | ||||
|         for (var node : graph.getAllNodes()) { | ||||
|             graph.removeNode(node); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private Optional<Node> findClickedNode(MouseEvent e) { | ||||
|         return graph.getAllNodes() | ||||
|             .stream() | ||||
|             .filter(n -> | ||||
|                 n.inside(e.getX(), e.getY())) | ||||
|             .findFirst(); | ||||
|     } | ||||
| 
 | ||||
|     private void draw(Drawable d) { | ||||
|         d.fill(Color.BLACK); | ||||
|         d.rect(0, 0, getWidth(), getHeight()); | ||||
| 
 | ||||
|         d.strokeWeight(1); | ||||
|         d.fill(Color.WHITE); | ||||
|         for (var node : graph.getAllNodes()) { | ||||
|             for (var child : graph.getChildrenForNode(node)) { | ||||
|                 d.line(node.pos.x, node.pos.y, child.pos.x, child.pos.y); | ||||
| 
 | ||||
|                 var v = child.pos | ||||
|                     .copy() | ||||
|                     .sub(node.pos); | ||||
|                 var r = 4; | ||||
|                 var p = v.copy() | ||||
|                     .setMag(v.mag() - child.radius - r) | ||||
|                     .add(node.pos); | ||||
| 
 | ||||
|                 d.rotated(v.angle(), p.x, p.y, () -> | ||||
|                     d.triangle( | ||||
|                         p.x+r, p.y, | ||||
|                         p.x-r, p.y-r, | ||||
|                         p.x-r, p.y+r)); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         for (var node : graph.getAllNodes()) { | ||||
|             d.fill(node.color); | ||||
|             d.ellipse(node.pos.x, node.pos.y, node.radius * 2, node.radius * 2); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public void updateLoop() { | ||||
|         var last = System.currentTimeMillis(); | ||||
|         var acc = 0; | ||||
| 
 | ||||
|         while (running) { | ||||
|             while (acc > gruphi.getFrameDelay()) { | ||||
|                 update(); | ||||
|                 acc -= gruphi.getFrameDelay(); | ||||
|             } | ||||
|             repaint(); | ||||
| 
 | ||||
|             var current = System.currentTimeMillis(); | ||||
|             acc += current - last; | ||||
|             last = current; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private void update() { | ||||
|         if (selected != null) { | ||||
|             selected.pos.add(vel); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										46
									
								
								src/main/java/de/oshgnacknak/gruphi/GruphiMain.java
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								src/main/java/de/oshgnacknak/gruphi/GruphiMain.java
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,46 @@ | |||
| package de.oshgnacknak.gruphi; | ||||
| 
 | ||||
| import h07.graph.DirectedGraphFactory; | ||||
| 
 | ||||
| import java.util.function.BiPredicate; | ||||
| 
 | ||||
| public class GruphiMain { | ||||
| 
 | ||||
|     public static void main(String[] args) { | ||||
|         var spacing = 50; | ||||
| 
 | ||||
|         var gruphi = new Gruphi() { | ||||
| 
 | ||||
|             @Override | ||||
|             public long getFrameDelay() { | ||||
|                 return 1000 / 60; | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public double getVelocity() { | ||||
|                 return 5; | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public double getGridSpacing() { | ||||
|                 return spacing; | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public BiPredicate<Node, Node> getNeighbourPredicate() { | ||||
|                 return (a, b) -> | ||||
|                     a.pos.dist(b.pos) <= spacing; | ||||
|             } | ||||
| 
 | ||||
|             @Override | ||||
|             public DirectedGraphFactory<Node, Double> getDirectedGraphFactory() { | ||||
|                 return DirectedGraphFactory.defaultFactory(); | ||||
|             } | ||||
|         }; | ||||
| 
 | ||||
|         var frame = new GruphiFrame(gruphi); | ||||
|         frame.setVisible(true); | ||||
|         frame.updateLoop(); | ||||
|         System.exit(0); | ||||
|     } | ||||
| } | ||||
|  | @ -11,12 +11,12 @@ public class MazeGenerator<V> { | |||
|     private final Random random; | ||||
|     private final DirectedGraph<V, Double> graph; | ||||
|     private final Set<V> visited; | ||||
|     private final BiPredicate<V, V> areNeighbours; | ||||
|     private final BiPredicate<V, V> neighbourPredicate; | ||||
| 
 | ||||
|     public MazeGenerator(DirectedGraph<V, Double> graph, BiPredicate<V, V> areNeighbours) { | ||||
|     public MazeGenerator(DirectedGraph<V, Double> graph, BiPredicate<V, V> neighbourPredicate) { | ||||
|         this.random = new Random(); | ||||
|         this.graph = graph; | ||||
|         this.areNeighbours = areNeighbours; | ||||
|         this.neighbourPredicate = neighbourPredicate; | ||||
|         this.visited = new HashSet<>(); | ||||
|     } | ||||
| 
 | ||||
|  | @ -54,7 +54,7 @@ public class MazeGenerator<V> { | |||
|             .stream() | ||||
|             .filter(n -> | ||||
|                 n != node | ||||
|                 && areNeighbours.test(node, n) | ||||
|                 && neighbourPredicate.test(node, n) | ||||
|                 && !visited.contains(n)) | ||||
|             .collect(Collectors.toList()); | ||||
|     } | ||||
|  |  | |||
		Reference in a new issue