package Main;
-public class AStar{
+import javax.swing.JOptionPane;
+
+public class AStar implements Runnable {
private Map map;
private int x, y;
PathfinderUtils.path.clear();
}
- public void start() {
+ @Override
+ public void run() {
searchPath(PathfinderUtils.startNode);
}
public void searchPath(Node parent) {
- for (int i = 0; i < 4; i++) {
- x = (int) Math.round(parent.getX() + (-map.getNodeSize()* Math.cos((Math.PI / 2) * i)));
- y = (int) Math.round(parent.getY() + (-map.getNodeSize() * Math.sin((Math.PI / 2) * i)));
+ while (!map.isFinished()) {
+ for (int i = 0; i < 4; i++) {
+ x = (int) Math.round(parent.getX() + (-map.getNodeSize() * Math.cos((Math.PI / 2) * i)));
+ y = (int) Math.round(parent.getY() + (-map.getNodeSize() * Math.sin((Math.PI / 2) * i)));
- calculateOpenNode(x, y, parent);
- }
+ calculateOpenNode(x, y, parent);
+ }
- if((parent = getNextBestNode()) == null)
- return;
+ if ((parent = getNextBestNode()) == null)
+ return;
- PathfinderUtils.closedNodes.add(parent);
- PathfinderUtils.openNodes.remove(parent);
+ PathfinderUtils.closedNodes.add(parent);
+ PathfinderUtils.openNodes.remove(parent);
- if (!map.isFinished())
- searchPath(parent);
+ map.repaint();
+ try {
+ Thread.sleep(map.speed);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
}
public void calculateOpenNode(int nextX, int nextY, Node parent) {
PathfinderUtils.drawPath();
map.setFinished(true);
map.setRunning(false);
- map.repaint();
return;
}
openNode.setF(f);
PathfinderUtils.openNodes.add(openNode);
+ map.repaint();
}
public Node getNextBestNode() {
}
map.setFinished(true);
- map.repaint();
+ map.setRunning(false);
+ JOptionPane.showMessageDialog(null, "No path found!", "Pathfinder error", JOptionPane.ERROR_MESSAGE);
return null;
}
}
private boolean isFinished = false;
private boolean running = false;
+
private int size = 20;
+ int speed = 10;
public Map() {
this.setBackground(new Color(40, 40, 40));
g.fillRect(node.getX() + 1, node.getY() + 1, size - 1, size - 1);
}
- // Draws open nodes
+ // Draws external nodes
g.setColor(new Color(69, 133, 136));
- for (Node node : PathfinderUtils.openNodes) {
- g.fillRect(node.getX() + 1, node.getY() + 1, size - 1, size - 1);
+ for (int i = 0; i < PathfinderUtils.openNodes.size(); i++) {
+ g.fillRect(PathfinderUtils.openNodes.get(i).getX() + 1, PathfinderUtils.openNodes.get(i).getY() + 1,
+ size - 1, size - 1);
}
- // Draws closed nodes
+ // Draws internal nodes
g.setColor(new Color(77, 77, 77));
- for (Node node : PathfinderUtils.closedNodes) {
- g.fillRect(node.getX() + 1, node.getY() + 1, size - 1, size - 1);
+ for (int i = 0; i < PathfinderUtils.closedNodes.size(); i++) {
+ g.fillRect(PathfinderUtils.closedNodes.get(i).getX() + 1, PathfinderUtils.closedNodes.get(i).getY() + 1,
+ size - 1, size - 1);
}
// if path is found start drawing the shortest path
// Drawing on the grid
public void mapDrawing(MouseEvent e) {
// Creating nodes
+ Node node = new Node(e.getX() - (e.getX() % size), e.getY() - (e.getY() % size));
+
if (SwingUtilities.isLeftMouseButton(e)) {
+ // Start node
if (key == 's') {
- int posX = e.getX() - (e.getX() % size);
- int posY = e.getY() - (e.getY() % size);
-
- if (PathfinderUtils.startNode == null && PathfinderUtils.endNode == null) {
- PathfinderUtils.startNode = new Node(posX, posY);
- } else if (PathfinderUtils.endNode != null && PathfinderUtils.startNode == null) {
- if (posX == PathfinderUtils.endNode.getX() && posY == PathfinderUtils.endNode.getY()) {
- JOptionPane.showMessageDialog(null, "Same node error",
- "End node and start node can't be the same node", JOptionPane.ERROR_MESSAGE);
+ // If both start and end node don't exist just create the start node
+ if (PathfinderUtils.startNode == null && PathfinderUtils.endNode == null)
+ // Set the node as the start node
+ PathfinderUtils.startNode = node;
+
+ // If the end node exists check if the node is the same else create the start
+ // node
+ else if (PathfinderUtils.endNode != null && PathfinderUtils.startNode == null) {
+ if (PathfinderUtils.isSameNode(node, PathfinderUtils.endNode)) {
+ // Send an error message saying that start and end node are the same
+ JOptionPane.showMessageDialog(null, "End node and start node can't be the same node",
+ "Same node error", JOptionPane.ERROR_MESSAGE);
return;
}
- PathfinderUtils.startNode = new Node(posX, posY);
- } else {
- if (posX == PathfinderUtils.endNode.getX() && posY == PathfinderUtils.endNode.getY()) {
- JOptionPane.showMessageDialog(null, "Same node error",
- "End node and start node can't be the same node", JOptionPane.ERROR_MESSAGE);
+
+ // Set the node as the start node
+ PathfinderUtils.startNode = node;
+
+ }
+
+ // If they both exist check if same node else move che start node
+ else {
+ if (PathfinderUtils.isSameNode(node, PathfinderUtils.endNode)) {
+ JOptionPane.showMessageDialog(null, "End node and start node can't be the same node",
+ "Same node error", JOptionPane.ERROR_MESSAGE);
return;
}
- PathfinderUtils.startNode.setX(posX);
- PathfinderUtils.startNode.setY(posY);
+ // Change start node coordinates without creating a new node
+ PathfinderUtils.startNode.setX(node.getX());
+ PathfinderUtils.startNode.setY(node.getY());
}
-
- repaint();
}
+ // End node
else if (key == 'e') {
- int posX = e.getX() - (e.getX() % size);
- int posY = e.getY() - (e.getY() % size);
-
- if (PathfinderUtils.startNode == null && PathfinderUtils.endNode == null) {
- PathfinderUtils.endNode = new Node(posX, posY);
- } else if (PathfinderUtils.startNode != null && PathfinderUtils.endNode == null) {
- if (posX == PathfinderUtils.startNode.getX() && posY == PathfinderUtils.startNode.getY()) {
- JOptionPane.showMessageDialog(null, "Same node error",
- "End node and start node can't be the same node", JOptionPane.ERROR_MESSAGE);
+ // If both start and end node don't exist just create the end node
+ if (PathfinderUtils.startNode == null && PathfinderUtils.endNode == null)
+ // Set the node as the end node
+ PathfinderUtils.endNode = node;
+
+ // If the start node exists check if the node is the same else create the end node
+ else if (PathfinderUtils.startNode != null && PathfinderUtils.endNode == null) {
+ if (PathfinderUtils.isSameNode(node, PathfinderUtils.startNode)) {
+ // Send an error message saying that start and end node are the same
+ JOptionPane.showMessageDialog(null, "End node and start node can't be the same node",
+ "Same node error", JOptionPane.ERROR_MESSAGE);
return;
}
- PathfinderUtils.endNode = new Node(posX, posY);
- } else {
- if (posX == PathfinderUtils.startNode.getX() && posY == PathfinderUtils.startNode.getY()) {
- JOptionPane.showMessageDialog(null, "Same node error",
- "End node and start node can't be the same node", JOptionPane.ERROR_MESSAGE);
+
+ // Set the node as the end node
+ PathfinderUtils.endNode = node;
+
+ }
+ // If they both exist check if same node else move the end node
+ else {
+ if (PathfinderUtils.startNode != null && PathfinderUtils.endNode == null) {
+ JOptionPane.showMessageDialog(null, "End node and start node can't be the same node",
+ "Same node error", JOptionPane.ERROR_MESSAGE);
return;
}
- PathfinderUtils.endNode.setX(posX);
- PathfinderUtils.endNode.setY(posY);
+ // Change end node coordinates without creating a new node
+ PathfinderUtils.endNode.setX(node.getX());
+ PathfinderUtils.endNode.setY(node.getY());
}
-
- repaint();
}
+ // Barriers
else {
- int posX = e.getX() - (e.getX() % size);
- int posY = e.getY() - (e.getY() % size);
- Node barrierNode = new Node(posX, posY);
-
- if (PathfinderUtils.startNode != null)
- if (PathfinderUtils.isSameNode(barrierNode, PathfinderUtils.startNode))
- return;
- if (PathfinderUtils.endNode != null)
- if (PathfinderUtils.isSameNode(barrierNode, PathfinderUtils.endNode))
- return;
-
- PathfinderUtils.barriers.add(barrierNode);
+ // If the start/end node exists check if the node is the same
+ // If it is return
+ if (PathfinderUtils.startNode != null && PathfinderUtils.isSameNode(node, PathfinderUtils.startNode))
+ return;
+ if (PathfinderUtils.endNode != null && PathfinderUtils.isSameNode(node, PathfinderUtils.endNode))
+ return;
- repaint();
+ PathfinderUtils.barriers.add(node);
}
+
+ // Update the UI with barrier/start/end node
+ repaint();
}
// Deleting nodes
if (key == 's' && PathfinderUtils.startNode != null) {
if (PathfinderUtils.startNode.getX() == posX && PathfinderUtils.startNode.getY() == posY) {
PathfinderUtils.startNode = null;
- repaint();
}
}
else if (key == 'e' && PathfinderUtils.endNode != null) {
if (PathfinderUtils.endNode.getX() == posX && PathfinderUtils.endNode.getY() == posY) {
PathfinderUtils.endNode = null;
- repaint();
}
}
if (nodeID != -1) {
PathfinderUtils.remove(nodeID);
}
- repaint();
}
+
+ repaint();
}
}
if (key == KeyEvent.VK_SPACE) {
if (running == false && isFinished == false) {
if (PathfinderUtils.startNode == null || PathfinderUtils.endNode == null) {
- JOptionPane.showMessageDialog(null, "Missing node", "Missing start or end node",
+ JOptionPane.showMessageDialog(null, "Missing start or end node", "Missing node",
JOptionPane.ERROR_MESSAGE);
return;
}
running = true;
- new AStar(this).start();
+
+ // AStar needs to extend runnable because otherwise map.repaint() will wait to update the UI
+ new Thread(new AStar(this)).start();
} else if (running == false && isFinished == true) {
PathfinderUtils.barriers.clear();
PathfinderUtils.openNodes.clear();
<?xml version="1.0" encoding="UTF-8"?>
-<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report.xsd" name="Main.AppTest" time="0.036" tests="1" errors="0" skipped="0" failures="0">
+<testsuite xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://maven.apache.org/surefire/maven-surefire-plugin/xsd/surefire-test-report.xsd" name="Main.AppTest" time="0.03" tests="1" errors="0" skipped="0" failures="0">
<properties>
- <property name="java.specification.version" value="16"/>
+ <property name="awt.toolkit" value="sun.awt.X11.XToolkit"/>
+ <property name="java.specification.version" value="11"/>
+ <property name="sun.cpu.isalist" value=""/>
<property name="sun.jnu.encoding" value="ANSI_X3.4-1968"/>
- <property name="java.class.path" value="/home/leo/Docs/Proj/pathfinding-visualizer/target/test-classes:/home/leo/Docs/Proj/pathfinding-visualizer/target/classes:/home/leo/.m2/repository/junit/junit/4.11/junit-4.11.jar:/home/leo/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:"/>
+ <property name="java.class.path" value="/home/leo/Docs/Proj/Pathfinder/target/test-classes:/home/leo/Docs/Proj/Pathfinder/target/classes:/home/leo/.m2/repository/junit/junit/4.11/junit-4.11.jar:/home/leo/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:"/>
<property name="java.vm.vendor" value="Oracle Corporation"/>
<property name="sun.arch.data.model" value="64"/>
- <property name="java.vendor.url" value="https://java.oracle.com/"/>
+ <property name="java.vendor.url" value="http://java.oracle.com/"/>
+ <property name="user.timezone" value=""/>
+ <property name="java.vm.specification.version" value="11"/>
<property name="os.name" value="Linux"/>
- <property name="java.vm.specification.version" value="16"/>
<property name="sun.java.launcher" value="SUN_STANDARD"/>
<property name="user.country" value="US"/>
- <property name="sun.boot.library.path" value="/home/leo/.config/jdks/openjdk-16.0.2/lib"/>
- <property name="sun.java.command" value="/home/leo/Docs/Proj/pathfinding-visualizer/target/surefire/surefirebooter16569093588158702030.jar /home/leo/Docs/Proj/pathfinding-visualizer/target/surefire 2021-08-08T09-03-56_502-jvmRun1 surefire6723173350746780523tmp surefire_013466448355498983315tmp"/>
+ <property name="sun.boot.library.path" value="/usr/lib/jvm/openjdk11-bin/lib"/>
+ <property name="sun.java.command" value="/home/leo/Docs/Proj/Pathfinder/target/surefire/surefirebooter4082728071684051500.jar /home/leo/Docs/Proj/Pathfinder/target/surefire 2021-11-19T20-44-45_157-jvmRun1 surefire17835783201909300860tmp surefire_02185374437203797851tmp"/>
<property name="jdk.debug" value="release"/>
- <property name="surefire.test.class.path" value="/home/leo/Docs/Proj/pathfinding-visualizer/target/test-classes:/home/leo/Docs/Proj/pathfinding-visualizer/target/classes:/home/leo/.m2/repository/junit/junit/4.11/junit-4.11.jar:/home/leo/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:"/>
+ <property name="surefire.test.class.path" value="/home/leo/Docs/Proj/Pathfinder/target/test-classes:/home/leo/Docs/Proj/Pathfinder/target/classes:/home/leo/.m2/repository/junit/junit/4.11/junit-4.11.jar:/home/leo/.m2/repository/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.jar:"/>
<property name="sun.cpu.endian" value="little"/>
<property name="user.home" value="/home/leo"/>
<property name="user.language" value="en"/>
<property name="java.specification.vendor" value="Oracle Corporation"/>
- <property name="java.version.date" value="2021-07-20"/>
- <property name="java.home" value="/home/leo/.config/jdks/openjdk-16.0.2"/>
+ <property name="java.version.date" value="2018-09-25"/>
+ <property name="java.home" value="/usr/lib/jvm/openjdk11-bin"/>
<property name="file.separator" value="/"/>
- <property name="basedir" value="/home/leo/Docs/Proj/pathfinding-visualizer"/>
- <property name="java.vm.compressedOopsMode" value="32-bit"/>
+ <property name="basedir" value="/home/leo/Docs/Proj/Pathfinder"/>
+ <property name="java.vm.compressedOopsMode" value="Zero based"/>
<property name="line.separator" value=" "/>
- <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
<property name="java.specification.name" value="Java Platform API Specification"/>
- <property name="surefire.real.class.path" value="/home/leo/Docs/Proj/pathfinding-visualizer/target/surefire/surefirebooter16569093588158702030.jar"/>
+ <property name="java.vm.specification.vendor" value="Oracle Corporation"/>
+ <property name="java.awt.graphicsenv" value="sun.awt.X11GraphicsEnvironment"/>
+ <property name="surefire.real.class.path" value="/home/leo/Docs/Proj/Pathfinder/target/surefire/surefirebooter4082728071684051500.jar"/>
<property name="sun.management.compiler" value="HotSpot 64-Bit Tiered Compilers"/>
- <property name="java.runtime.version" value="16.0.2+7-67"/>
+ <property name="java.runtime.version" value="11+28"/>
<property name="user.name" value="leo"/>
<property name="path.separator" value=":"/>
- <property name="os.version" value="5.13.8_1"/>
+ <property name="os.version" value="5.13.19_1"/>
<property name="java.runtime.name" value="OpenJDK Runtime Environment"/>
<property name="file.encoding" value="ANSI_X3.4-1968"/>
<property name="java.vm.name" value="OpenJDK 64-Bit Server VM"/>
+ <property name="java.vendor.version" value="18.9"/>
<property name="localRepository" value="/home/leo/.m2/repository"/>
- <property name="java.vendor.url.bug" value="https://bugreport.java.com/bugreport/"/>
+ <property name="java.vendor.url.bug" value="http://bugreport.java.com/bugreport/"/>
<property name="java.io.tmpdir" value="/tmp"/>
- <property name="java.version" value="16.0.2"/>
- <property name="user.dir" value="/home/leo/Docs/Proj/pathfinding-visualizer"/>
+ <property name="java.version" value="11"/>
+ <property name="user.dir" value="/home/leo/Docs/Proj/Pathfinder"/>
<property name="os.arch" value="amd64"/>
<property name="java.vm.specification.name" value="Java Virtual Machine Specification"/>
+ <property name="java.awt.printerjob" value="sun.print.PSPrinterJob"/>
+ <property name="sun.os.patch.level" value="unknown"/>
<property name="java.library.path" value="/usr/java/packages/lib:/usr/lib64:/lib64:/lib:/usr/lib"/>
- <property name="java.vm.info" value="mixed mode, sharing"/>
<property name="java.vendor" value="Oracle Corporation"/>
- <property name="java.vm.version" value="16.0.2+7-67"/>
+ <property name="java.vm.info" value="mixed mode"/>
+ <property name="java.vm.version" value="11+28"/>
<property name="sun.io.unicode.encoding" value="UnicodeLittle"/>
- <property name="java.class.version" value="60.0"/>
+ <property name="java.class.version" value="55.0"/>
</properties>
<testcase name="shouldAnswerWithTrue" classname="Main.AppTest" time="0.001"/>
</testsuite>
\ No newline at end of file