diff --git a/src/main/java/Assignments/A1/view/BoardViewCodeBehind.java b/src/main/java/Assignments/A1/view/BoardViewCodeBehind.java index d1053ff..f38eed3 100644 --- a/src/main/java/Assignments/A1/view/BoardViewCodeBehind.java +++ b/src/main/java/Assignments/A1/view/BoardViewCodeBehind.java @@ -6,6 +6,12 @@ import javafx.event.ActionEvent; import javafx.fxml.FXML; import javafx.scene.control.*; +/** + * Code Behind file for MainView.fxml + * + * @author Jonathan Turner + * @version Spring 2024 + */ public class BoardViewCodeBehind { @FXML @@ -89,6 +95,11 @@ public class BoardViewCodeBehind { this.viewModel.runPerformanceCheck(); } + @FXML + void openPerformance(ActionEvent event) { + this.viewModel.openPerf(); + } + public void onGenerateBoard(ActionEvent actionEvent) { this.viewModel.generateBoard(); } @@ -111,11 +122,6 @@ public class BoardViewCodeBehind { } - @FXML - void openPerformance(ActionEvent event) { - this.viewModel.openPerf(); - } - public void onDFS(ActionEvent actionEvent) { viewModel.setSelectedAlg("DFS"); this.menu_alg.textProperty().set(this.menu_alg.getItems().get(0).textProperty().get()); diff --git a/src/main/java/Assignments/A1/view/MainViewModel.java b/src/main/java/Assignments/A1/view/MainViewModel.java index f430888..fcc3c1f 100644 --- a/src/main/java/Assignments/A1/view/MainViewModel.java +++ b/src/main/java/Assignments/A1/view/MainViewModel.java @@ -19,15 +19,14 @@ import java.util.Stack; public class MainViewModel { /* Private Fields used to bind */ - private StringProperty currentBoardProperty, algSpeedProperty; - private StringProperty iterationCounter; - private BooleanProperty expanded, DFS, UCS, BFS, AStar, solvingAlgErr, genBoardErr, disclaimer, openPerf, runPerf; + private final StringProperty currentBoardProperty, algSpeedProperty, iterationCounter; + private final BooleanProperty expanded, DFS, UCS, BFS, AStar, solvingAlgErr, genBoardErr, disclaimer, openPerf, runPerf; private BoardNode current = new BoardNode(new Board(), null); private TreeItem solvedRootNode = null; /* Private Fields used for traversing/creating nodes. */ private BoardNode solvedRootBoardNode = null; - private long[][] hasRanPerformance; + private final long[][] hasRanPerformance; private String selectedAlg; /** @@ -57,85 +56,24 @@ public class MainViewModel { this.hasRanPerformance = new long[4][102]; } - /** + * Generates the board and sets the board on view to new board. * + * @precondition none + * @postcondition none */ - public void runPerformanceCheck() { - Solver solver = null; - int alg = -1; - if (this.selectedAlg.equals("DFS") && this.hasRanPerformance[0][0] == 0) { - solver = new DFS(); - alg = 0; - } else if (this.selectedAlg.equals("UCS") && this.hasRanPerformance[1][0] == 0) { - solver = new PriorityTraversal(new UCS()); - alg = 1; - } else if (this.selectedAlg.equals("BFS") && this.hasRanPerformance[2][0] == 0) { - solver = new PriorityTraversal(new BFS()); - alg = 2; - } else if (this.selectedAlg.equals("AStar") && this.hasRanPerformance[3][0] == 0) { - solver = new PriorityTraversal(new AStar()); - alg = 3; - } - - if (solver != null) { - for (int i = 0; i < 100; i++) { - Board board = BoardGenerator.generateBoard(); - System.out.println(board); - long start = new Date().getTime(); - BoardNode node = solver.traverse(board); - long end = new Date().getTime(); - System.out.println(node.board + "\n"); - if (node != null) { - this.hasRanPerformance[alg][i + 2] = end - start; - this.currentBoardProperty.setValue(node.board.toString()); - } else { - this.hasRanPerformance[alg][i+2] = -1; - } - iterationCounter.setValue("Performing Analysis Iteration: " + (i+1) + "/100"); - } - this.hasRanPerformance[alg][0] = 1; - - this.runPerf.setValue(false); - this.openPerf.setValue(true); - } - - for (int i = 1; i < this.hasRanPerformance[alg].length; i++) { - System.out.println(this.hasRanPerformance[alg][i]); - } - } - - public void setSelectedAlg(String value) { - this.selectedAlg = value; - this.DFS.set(value.equals("DFS")); - this.UCS.set(value.equals("UCS")); - this.BFS.set(value.equals("BFS")); - this.AStar.set(value.equals("AStar")); - - this.disclaimer.setValue(value.equals("DFS")); - this.openPerf.setValue(this.hasRanPerformance[convertValueToInt(value)][0] == 1); - this.runPerf.setValue(this.hasRanPerformance[convertValueToInt(value)][0] == 0); - if (this.hasRanPerformance[convertValueToInt(value)][0] == 0) { - this.iterationCounter.set(""); - } - } - - private int convertValueToInt(String value) { - if (value.equals("DFS")) return 0; - if (value.equals("UCS")) return 1; - if (value.equals("BFS")) return 2; - return 3; - } - - public StringProperty getCurrentBoardProperty() { - return this.currentBoardProperty; - } - public void generateBoard() { this.current = new BoardNode(BoardGenerator.generateBoard(), null); currentBoardProperty.set(this.current.board.toString()); } + /** + * Solves the current board by checking for which alg is selected, then will solve that board + * with the given alg that implements the Solver interface. + * + * @precondition menuItem != null && (board != solver || board != null) + * @postcondition the board is solved. + */ public void solveBoard() { if (selectedAlg == null || selectedAlg.isEmpty()) { this.solvingAlgErr.setValue(true); @@ -175,6 +113,88 @@ public class MainViewModel { this.current = solved; } + /** + * Sets the values of the data using the View's Property files and Bindings. + * + * @precondition none + * @postcondition none + * + * @param value the menu item value. + */ + public void setSelectedAlg(String value) { + this.selectedAlg = value; + this.DFS.set(value.equals("DFS")); + this.UCS.set(value.equals("UCS")); + this.BFS.set(value.equals("BFS")); + this.AStar.set(value.equals("AStar")); + + this.disclaimer.setValue(value.equals("DFS")); + this.openPerf.setValue(this.hasRanPerformance[convertValueToInt(value)][0] == 1); + this.runPerf.setValue(this.hasRanPerformance[convertValueToInt(value)][0] == 0); + if (this.hasRanPerformance[convertValueToInt(value)][0] == 0) { + this.iterationCounter.set(""); + } + } + + /** + * Runs through the selected algorithm and will run it 100 times. It will collect data from these runs + * and store them. It will then allow you to view the data in a new windows and the button will appear. + * + * @precondition none + * @postcondition the performance is taken. + */ + public void runPerformanceCheck() { + Solver solver = null; + int alg = -1; + if (this.selectedAlg.equals("DFS") && this.hasRanPerformance[0][0] == 0) { + solver = new DFS(); + alg = 0; + } else if (this.selectedAlg.equals("UCS") && this.hasRanPerformance[1][0] == 0) { + solver = new PriorityTraversal(new UCS()); + alg = 1; + } else if (this.selectedAlg.equals("BFS") && this.hasRanPerformance[2][0] == 0) { + solver = new PriorityTraversal(new BFS()); + alg = 2; + } else if (this.selectedAlg.equals("AStar") && this.hasRanPerformance[3][0] == 0) { + solver = new PriorityTraversal(new AStar()); + alg = 3; + } + int averageNodes = 0; + if (solver != null) { + for (int i = 0; i < 100; i++) { + Board board = BoardGenerator.generateBoard(); + System.out.println(board); + long start = new Date().getTime(); + BoardNode node = solver.traverse(board); + long end = new Date().getTime(); + System.out.println(node.board + "\n"); + if (node != null) { + this.hasRanPerformance[alg][i + 2] = end - start; + this.currentBoardProperty.setValue(node.board.toString()); + averageNodes += solver.getNumOfNodes(); + updateDisplay(); + } else { + this.hasRanPerformance[alg][i+2] = -1; + } + iterationCounter.setValue("Performing Analysis Iteration: " + (i+1) + "/100"); + } + this.hasRanPerformance[alg][0] = 1; + this.hasRanPerformance[alg][1] = averageNodes; + this.runPerf.setValue(false); + this.openPerf.setValue(true); + } + + for (int i = 1; i < this.hasRanPerformance[alg].length; i++) { + System.out.println(this.hasRanPerformance[alg][i]); + } + } + + /** + * Opens the performance files that were previously generated. Is only visible when performance is already generated. + * + * @precondition performance == generated + * @postcondition performance is displayed in Alert. + */ public void openPerf() { long totalTime = 0; int success = 0; @@ -201,52 +221,26 @@ public class MainViewModel { perf.setHeaderText(success + "/" + 100 + " Succeeded."); String results = "Shortest Run: " + shortest + "ms\n" + "Longest Run: " + longest + "ms\n" + - "Average Time: " + average + "ms"; + "Average Time: " + average + "ms" + "\n" + + "Average Nodes: " + (this.hasRanPerformance[convertValueToInt(this.selectedAlg)][1]/success); perf.setContentText(results); perf.show(); } + /** + * Is used to update the display with the current board. + * + * @precondition none + * @postcondition the dispaly is updated. + */ public void updateDisplay() { TreeItem newRoot = null; newRoot = this.rebuildTree(this.solvedRootBoardNode, this.expanded.getValue()); this.solvedRootNode = newRoot; } - private TreeItem rebuildTree(BoardNode root, boolean expanded) { - if (this.selectedAlg != null) { - if (this.selectedAlg.equals("DFS")) { - Stack generations = new Stack<>(); - BoardNode temp = this.current; - while (temp != null) { - generations.push(temp); - temp = temp.parent; - } - TreeItem rootItem = new TreeItem<>(root); - TreeItem currItem = rootItem; - while (!generations.isEmpty()) { - TreeItem child = new TreeItem<>(generations.pop()); - currItem.getChildren().add(child); - currItem.setExpanded(expanded); - currItem = child; - } - return rootItem; - } else { - TreeItem treeItem = new TreeItem<>(root); - for (BoardNode child : root.children) { - TreeItem childItem = rebuildTree(child, expanded); - treeItem.getChildren().add(childItem); - } - treeItem.setExpanded(expanded); - - return treeItem; - } - } - return new TreeItem<>(); - } - /* Getters for bindings */ - public TreeItem getSolvedRootNode() { return solvedRootNode; } @@ -306,4 +300,49 @@ public class MainViewModel { public BooleanProperty runPerfProperty() { return runPerf; } + + public StringProperty getCurrentBoardProperty() { + return this.currentBoardProperty; + } + + /* End of Public Methods. Private Fields Only */ + + private TreeItem rebuildTree(BoardNode root, boolean expanded) { + if (this.selectedAlg != null) { + if (this.selectedAlg.equals("DFS")) { + Stack generations = new Stack<>(); + BoardNode temp = this.current; + while (temp != null) { + generations.push(temp); + temp = temp.parent; + } + TreeItem rootItem = new TreeItem<>(root); + TreeItem currItem = rootItem; + while (!generations.isEmpty()) { + TreeItem child = new TreeItem<>(generations.pop()); + currItem.getChildren().add(child); + currItem.setExpanded(expanded); + currItem = child; + } + return rootItem; + } else { + TreeItem treeItem = new TreeItem<>(root); + for (BoardNode child : root.children) { + TreeItem childItem = rebuildTree(child, expanded); + treeItem.getChildren().add(childItem); + } + treeItem.setExpanded(expanded); + + return treeItem; + } + } + return new TreeItem<>(); + } + + private int convertValueToInt(String value) { + if (value.equals("DFS")) return 0; + if (value.equals("UCS")) return 1; + if (value.equals("BFS")) return 2; + return 3; + } }