Pathfinding Dijkstra class

Covers the Dijkstra class of my pathfinding visualizer in java

Overview:

The Dijkstra class integrates the Dijkstra pathfinding algorithm into my pathfinding algorithm visualizer.

 

Design choices:

The Dijkstra algorithm is mostly unmodified except where it needs to be slowed to be properly visualized and where it must update the map.

Takeaways:

Slowing the algorithm proved harder in this project than I first though and I eventually had to use threading to solve the problem.

 

package Pathfinding;

import java.awt.*;
import java.util.PriorityQueue;

/**
 * @author Ian Sodersjerna
 * @date 6/30/2020
 */
public class Dijkstra extends Algorithm {
    private Node[][] nodeMap;
    private final Color visitedColor = Color.green;
    private final Color unvisitedColor = Color.red;


    /**
     * Constructor for algorithm
     *
     * @param panel panel to be used by algorithm
     */
    Dijkstra(mapPanel panel) {
        super(panel);
    }

    public void paintPath() {
        Node current = nodeMap[end.x][end.y];
        while (current.parent != null) {
            current = current.parent;
            this.panel.setPosition(current.position.x, current.position.y, Color.blue);
        }
        this.panel.setPosition(this.start, mapPanel.START_COLOR);
        this.panel.setPosition(this.end, mapPanel.END_COLOR);
        this.panel.paintComponent(this.panel.getGraphics());
    }

    @Override
    public void generatePath() throws IllegalArgumentException {
        nodeMap = new Node[size.x][size.y];
        PriorityQueue<Node> unvisited = new PriorityQueue<>();
        for (int i = 0; i < nodeMap.length; ++i) {
            for (int j = 0; j < nodeMap[0].length; ++j) {
                nodeMap[i][j] = new Node(new Point(i, j), Integer.MAX_VALUE);
                if (map[i][j] == 1) {
                    nodeMap[i][j].wall = true;
                }
            }
        }
        unvisited.add(nodeMap[start.x][start.y]);
        this.panel.setPosition(nodeMap[start.x][start.y].position, visitedColor);
        this.nodeMap[start.x][start.y].distance = 0;
        this.nodeMap[end.x][end.y].end = true;
        Node current = null;
        Node neighbor;
        while (!unvisited.isEmpty()) {
            current = unvisited.poll();
            if (current.distance == Integer.MAX_VALUE) {
                throw new IllegalArgumentException("course cannot be solved.");
            }
            //neighbors
            for (int i = -1; i <= 1; i++) {
                for (int j = -1; j <= 1; j++) {
                    // Insure the current node is not selected
                    if (i != 0 || j != 0) {
                        // If the neighbor is on the board
                        if ((current.position.x + i) >= 0 && (current.position.y + j) >= 0 && (current.position.x + i) < this.size.x && (current.position.y + j) < this.size.y) {
                            // If the neighbor is wall or inaccessible due to neighboring walls
                            if (this.nodeMap[current.position.x + i][current.position.y + j].wall || ((i != 0 && j != 0) && (this.nodeMap[current.position.x + i][current.position.y].wall && this.nodeMap[current.position.x][current.position.y + j].wall))) {
                                continue;
                            }
                            neighbor = nodeMap[current.position.x + i][current.position.y + j];
                            if (neighbor.distance > current.distance + distanceBetween(current.position, neighbor.position)) {
                                neighbor.distance = current.distance + distanceBetween(current.position, neighbor.position);
                                neighbor.parent = current;
                                unvisited.remove(neighbor);
                                unvisited.add(neighbor);
                                this.panel.setPosition(neighbor.position, unvisitedColor);
                            }
                        }
                    }
                }
            }
            this.panel.setPosition(current.position.x, current.position.y, visitedColor);
            if (current.end) {
                break;
            }
            if (!mapPanel.completed) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    GUI.panelTread.interrupt();
                    return;
                }
            }
        }
        if (current == null || !current.end) {
            GUI.panelTread.interrupt();
            throw new IllegalArgumentException("course cannot be solved.");
        }
        paintPath();
        GUI.panelTread.interrupt();
    }


    static class Node implements Comparable<Node> {
        private final Point position;
        private Node parent = null;
        private Integer distance;
        private boolean end = false, wall = false;

        @Override
        public int compareTo(Node node) {
            return this.distance.compareTo(node.distance);
        }

        Node(Point position, int dist) {
            this.position = position;
            this.distance = dist;
        }
    }
}