-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathMain.java
155 lines (130 loc) · 5.14 KB
/
Main.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import java.util.Random;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.stage.Stage;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.StackPane;
public class Main extends Application {
public static boolean isAnimationPlaying = false;
private static final int SIZE = 500; // Size in pixels of the grid
private static final int GRID_SIZE = 15; // Number of tiles in the grid
private ComboBox<String> algorithmSelect; // Drop down menu to select which algorithm to use
private Tile[][] tiles;
private Tile start;
private Tile goal;
@Override
public void start(Stage primaryStage) throws Exception {
// Root pane that holds the UI elements and the grid
BorderPane root = new BorderPane();
root.setPadding(new Insets(8, 8, 16, 8));
// Handles spacing of UI elements
GridPane grid = new GridPane();
grid.setHgap(10);
Label algorithmLabel = new Label("Algorithm:");
GridPane.setConstraints(algorithmLabel, 0, 0);
algorithmSelect = new ComboBox<>();
algorithmSelect.getItems().addAll("Breath First Search", "Greedy Best-First Search", "A*");
algorithmSelect.getSelectionModel().selectFirst();
GridPane.setConstraints(algorithmSelect, 1, 0);
Button runBtn = new Button("Run");
runBtn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
// Run button runs algorithm on a different thread than the GUI
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
StartAnimation();
}
});
thread.start();
}
});
GridPane.setConstraints(runBtn, 2, 0);
grid.getChildren().addAll(algorithmLabel, algorithmSelect, runBtn);
// Stackpane holds the tiles of the grid
StackPane stackPane = new StackPane();
stackPane.setPrefSize(SIZE, SIZE);
stackPane.setPadding(new Insets(8, 0, 0, 0));
Random rnd = new Random();
tiles = new Tile[GRID_SIZE][GRID_SIZE];
double tileSize = SIZE / GRID_SIZE;
for (int y = 0; y < GRID_SIZE; y++) {
for (int x = 0; x < GRID_SIZE; x++) {
Tile tile = new Tile(x, y, tileSize);
tile.setTranslateX(x * tileSize);
tile.setTranslateY(y * tileSize);
if(rnd.nextDouble() > 0.7)
tile.SetType(NodeType.BARRIER);
tiles[x][y] = tile;
stackPane.getChildren().add(tile);
}
}
// Initially sets the start and end tiles to the first and last element of the
// grid
tiles[0][0].SetType(NodeType.START);
tiles[GRID_SIZE - 1][GRID_SIZE - 1].SetType(NodeType.GOAL);
start = tiles[0][0];
goal = tiles[GRID_SIZE - 1][GRID_SIZE - 1];
root.setTop(grid);
root.setCenter(stackPane);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.setMaximized(true);
primaryStage.setTitle("Pathfinding Visualization");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
private void StartAnimation() {
// Quits if an animation is already playing, otherwise resets tiles
if (isAnimationPlaying) {
return;
} else {
ResetTiles();
}
isAnimationPlaying = true;
// Selects which pathfinding algorithm to use according to the drop down menu
switch (algorithmSelect.getValue()) {
case "Breath First Search":
Pathfinding.BreathFirstSearch(start, goal, tiles);
break;
case "Greedy Best-First Search":
Pathfinding.GreedyBestFirstSearch(start, goal, tiles);
break;
case "A*":
Pathfinding.AStar(start, goal, tiles);
break;
}
isAnimationPlaying = false;
start.SetType(NodeType.START);
goal.SetType(NodeType.GOAL);
}
// Finds the start and end nodes on the grid, and
// resets all tiles except barriers back to empty
private void ResetTiles() {
for (int y = 0; y < tiles.length; y++) {
for (int x = 0; x < tiles[0].length; x++) {
if (tiles[x][y].GetType() == NodeType.START) {
start = tiles[x][y];
continue;
}
if (tiles[x][y].GetType() == NodeType.GOAL) {
goal = tiles[x][y];
continue;
}
if (tiles[x][y].GetType() != NodeType.BARRIER) {
tiles[x][y].SetType(NodeType.EMPTY);
}
}
}
}
}