Java Project
Java Project
Submitted To:
Shruti
School of Computer Science and Engineering
Lovely Professional University, Phagwara, Punjab
Abhinshyam K
12110384, Roll number: 34
Introduction:
The PathFinding Visualiser project is a Java application that provides a visual representation
of pathfinding algorithms on a grid. It allows users to interactively create maps, set start and
finish points, and observe the algorithm's process of finding the shortest path between them.
The project implements two popular graph algorithms, Dijkstra's algorithm and A* algorithm,
to find the shortest path between two points on the grid. These algorithms use different
strategies to explore the grid and determine the optimal path based on certain criteria.
Dijkstra's algorithm, named after Dutch computer scientist Edsger W. Dijkstra, is a graph
search algorithm that finds the shortest path from a starting node to all other nodes in the
graph. It works by iteratively selecting the node with the smallest distance from the start and
updating the distances of its neighbors.
A* algorithm, on the other hand, is a more informed search algorithm that uses a heuristic
function to estimate the cost of reaching the goal from a given node. It combines the
advantages of Dijkstra's algorithm and greedy best-first search, making it more efficient in
finding the shortest path.
The PathFinding project provides a user-friendly interface for selecting algorithms, adjusting
grid size and obstacle density, and visualizing the search process. It serves as a valuable tool
for understanding and comparing different pathfinding algorithms in a visual and interactive
manner.
Screenshots of the Source code:
Screenshots of the Output:
Dijkstra’s Algorithms
A* Algorithm:
Generate Map:
Searching through the Map:
Source Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.border.Border;
import javax.swing.border.EtchedBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
//FRAME
JFrame frame;
//GENERAL VARIABLES
private int cells = 20;
private int delay = 30;
private double dense = .5;
private double density = (cells*cells)*.5;
private int startx = -1;
private int starty = -1;
private int finishx = -1;
private int finishy = -1;
private int tool = 0;
private int checks = 0;
private int length = 0;
private int curAlg = 0;
private int WIDTH = 850;
private final int HEIGHT = 650;
private final int MSIZE = 600;
private int CSIZE = MSIZE/cells;
//UTIL ARRAYS
private String[] algorithms = {"Dijkstra","A*"};
private String[] tools = {"Start","Finish","Wall", "Eraser"};
//BOOLEANS
private boolean solving = false;
//UTIL
Node[][] map;
Algorithm Alg = new Algorithm();
Random r = new Random();
//SLIDERS
JSlider size = new JSlider(1,5,2);
JSlider speed = new JSlider(0,500,delay);
JSlider obstacles = new JSlider(1,100,50);
//LABELS
JLabel algL = new JLabel("Algorithms");
JLabel toolL = new JLabel("Toolbox");
JLabel sizeL = new JLabel("Size:");
JLabel cellsL = new JLabel(cells+"x"+cells);
JLabel delayL = new JLabel("Delay:");
JLabel msL = new JLabel(delay+"ms");
JLabel obstacleL = new JLabel("Dens:");
JLabel densityL = new JLabel(obstacles.getValue()+"%");
JLabel checkL = new JLabel("Checks: "+checks);
JLabel lengthL = new JLabel("Path Length: "+length);
//BUTTONS
JButton searchB = new JButton("Start Search");
JButton resetB = new JButton("Reset");
JButton genMapB = new JButton("Generate Map");
JButton clearMapB = new JButton("Clear Map");
//DROP DOWN
JComboBox algorithmsBx = new JComboBox(algorithms);
JComboBox toolBx = new JComboBox(tools);
//PANELS
JPanel toolP = new JPanel();
//CANVAS
Map canvas;
//BORDER
Border loweredetched =
BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);
toolP.setBorder(BorderFactory.createTitledBorder(loweredetched,"Controls"));
int space = 25;
int buff = 45;
toolP.setLayout(null);
toolP.setBounds(10,10,210,600);
resetB.setBounds(40,space,120,25);
toolP.add(resetB);
space+=buff;
algL.setBounds(40,space,120,25);
toolP.add(algL);
space+=25;
toolL.setBounds(40,space,120,25);
toolP.add(toolL);
space+=25;
toolBx.setBounds(40,space,120,25);
toolP.add(toolBx);
space+=buff;
sizeL.setBounds(15,space,40,25);
toolP.add(sizeL);
size.setMajorTickSpacing(10);
size.setBounds(50,space,100,25);
toolP.add(size);
cellsL.setBounds(160,space,40,25);
toolP.add(cellsL);
space+=buff;
delayL.setBounds(15,space,50,25);
toolP.add(delayL);
speed.setMajorTickSpacing(5);
speed.setBounds(50,space,100,25);
toolP.add(speed);
msL.setBounds(160,space,40,25);
toolP.add(msL);
space+=buff;
obstacleL.setBounds(15,space,100,25);
toolP.add(obstacleL);
obstacles.setMajorTickSpacing(5);
obstacles.setBounds(50,space,100,25);
toolP.add(obstacles);
densityL.setBounds(160,space,100,25);
toolP.add(densityL);
space+=buff;
checkL.setBounds(15,space,100,25);
toolP.add(checkL);
space+=buff;
lengthL.setBounds(15,space,100,25);
toolP.add(lengthL);
space+=buff;
frame.getContentPane().add(toolP);
public Map() {
addMouseListener(this);
addMouseMotionListener(this);
}
g.drawString(map[x][y].getHops()+"/"+map[x][y].getEuclidDist(),
(x*CSIZE)+(CSIZE/2)-10, (y*CSIZE)+(CSIZE/2));
else
g.drawString(""+map[x][y].getHops(),
(x*CSIZE)+(CSIZE/2), (y*CSIZE)+(CSIZE/2));
*/
}
}
}
@Override
public void mouseDragged(MouseEvent e) {
try {
int x = e.getX()/CSIZE;
int y = e.getY()/CSIZE;
Node current = map[x][y];
if((tool == 2 || tool == 3) && (current.getType() != 0 &&
current.getType() != 1))
current.setType(tool);
Update();
} catch(Exception z) {}
}
@Override
public void mouseMoved(MouseEvent e) {}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {
resetMap(); //RESET THE MAP WHENEVER CLICKED
try {
int x = e.getX()/CSIZE; //GET THE X AND Y OF THE
MOUSE CLICK IN RELATION TO THE SIZE OF THE GRID
int y = e.getY()/CSIZE;
Node current = map[x][y];
switch(tool ) {
case 0: { //START NODE
if(current.getType()!=2) { //IF NOT WALL
if(startx > -1 && starty > -1) { //IF
START EXISTS SET IT TO EMPTY
map[startx][starty].setType(3);
map[startx][starty].setHops(-1);
}
current.setHops(0);
startx = x; //SET THE START X
AND Y
starty = y;
current.setType(0); //SET THE NODE
CLICKED TO BE START
}
break;
}
case 1: {//FINISH NODE
if(current.getType()!=2) { //IF NOT WALL
if(finishx > -1 && finishy > -1) //IF
FINISH EXISTS SET IT TO EMPTY
map[finishx][finishy].setType(3);
finishx = x; //SET THE FINISH X
AND Y
finishy = y;
current.setType(1); //SET THE NODE
CLICKED TO BE FINISH
}
break;
}
default:
if(current.getType() != 0 && current.getType()
!= 1)
current.setType(tool);
break;
}
Update();
} catch(Exception z) {} //EXCEPTION HANDLER
}
@Override
public void mouseReleased(MouseEvent e) {}
}
public void explore(Node current, int lastx, int lasty, int hops) {
//EXPLORE A NODE
if(current.getType()!=0 && current.getType() != 1) //CHECK THAT
THE NODE IS NOT THE START OR FINISH
current.setType(4); //SET IT TO EXPLORED
current.setLastNode(lastx, lasty); //KEEP TRACK OF THE NODE
THAT THIS NODE IS EXPLORED FROM
current.setHops(hops); //SET THE HOPS FROM THE START
checks++;
if(current.getType() == 1) { //IF THE NODE IS THE FINISH THEN
BACKTRACK TO GET THE PATH
backtrack(current.getLastX(), current.getLastY(),hops);
}
}
class Node {
Link:
• https://github.com/abhin-shyam/Pathfinding-using-java