Compare commits
No commits in common. "2da192b76dbc2206ef2c08e016e658b794ea23e9" and "6b88415ac20fc071670d266f84a700414763a267" have entirely different histories.
2da192b76d
...
6b88415ac2
@ -1,27 +0,0 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
|
||||||
<configuration default="false" name="CS3642-Artificial_Intelligence [javafx:run]" type="MavenRunConfiguration" factoryName="Maven" nameIsGenerated="true">
|
|
||||||
<MavenSettings>
|
|
||||||
<option name="myGeneralSettings" />
|
|
||||||
<option name="myRunnerSettings" />
|
|
||||||
<option name="myRunnerParameters">
|
|
||||||
<MavenRunnerParameters>
|
|
||||||
<option name="profiles">
|
|
||||||
<set />
|
|
||||||
</option>
|
|
||||||
<option name="goals">
|
|
||||||
<list>
|
|
||||||
<option value="javafx:run" />
|
|
||||||
</list>
|
|
||||||
</option>
|
|
||||||
<option name="pomFileName" />
|
|
||||||
<option name="profilesMap">
|
|
||||||
<map />
|
|
||||||
</option>
|
|
||||||
<option name="resolveToWorkspace" value="false" />
|
|
||||||
<option name="workingDirPath" value="$PROJECT_DIR$" />
|
|
||||||
</MavenRunnerParameters>
|
|
||||||
</option>
|
|
||||||
</MavenSettings>
|
|
||||||
<method v="2" />
|
|
||||||
</configuration>
|
|
||||||
</component>
|
|
11
pom.xml
11
pom.xml
@ -14,15 +14,20 @@
|
|||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.fxmisc.richtext</groupId>
|
||||||
|
<artifactId>richtextfx</artifactId>
|
||||||
|
<version>0.11.0</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjfx</groupId>
|
<groupId>org.openjfx</groupId>
|
||||||
<artifactId>javafx-controls</artifactId>
|
<artifactId>javafx-controls</artifactId>
|
||||||
<version>18.0.2</version>
|
<version>12.0.2</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.openjfx</groupId>
|
<groupId>org.openjfx</groupId>
|
||||||
<artifactId>javafx-fxml</artifactId>
|
<artifactId>javafx-fxml</artifactId>
|
||||||
<version>18.0.2</version>
|
<version>20.0.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<build>
|
<build>
|
||||||
@ -37,7 +42,7 @@
|
|||||||
<artifactId>javafx-maven-plugin</artifactId>
|
<artifactId>javafx-maven-plugin</artifactId>
|
||||||
<version>0.0.8</version>
|
<version>0.0.8</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<mainClass>Assignments/A1/GUILauncher</mainClass>
|
<mainClass>edu.jturn.cs3642.CS3642-Artificial_Intelligence/Assignments.A1.GUIDriver</mainClass>
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
|
@ -5,17 +5,20 @@ package Assignments.A1;
|
|||||||
import Assignments.A1.models.Board;
|
import Assignments.A1.models.Board;
|
||||||
import Assignments.A1.models.BoardGenerator;
|
import Assignments.A1.models.BoardGenerator;
|
||||||
import Assignments.A1.models.BoardNode;
|
import Assignments.A1.models.BoardNode;
|
||||||
import Assignments.A1.solving_algorithms.DFS;
|
import Assignments.A1.solving_algorithms.AStar;
|
||||||
import Assignments.A1.solving_algorithms.comparators.AStar;
|
import Assignments.A1.solving_algorithms.BFS;
|
||||||
|
import Assignments.A1.solving_algorithms.UCS;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Board will be used to save locations in a 2D array.
|
* Board will be used to save locations in a 2D array.
|
||||||
@ -41,16 +44,15 @@ public class Driver {
|
|||||||
BoardNode node = null;
|
BoardNode node = null;
|
||||||
for (int run = 0; run < runs; run++) {
|
for (int run = 0; run < runs; run++) {
|
||||||
Board board = BoardGenerator.generateBoard();
|
Board board = BoardGenerator.generateBoard();
|
||||||
DFS solver = new DFS();
|
// DFS solver = new DFS();
|
||||||
// BFS solver = new BFS();
|
// BFS solver = new BFS();
|
||||||
// UCS solver = new UCS();
|
// UCS solver = new UCS();
|
||||||
// AStar solver = new AStar();
|
AStar solver = new AStar();
|
||||||
Date start = new Date();
|
Date start = new Date();
|
||||||
BoardNode result = solver.traverse(board);
|
BoardNode result = solver.traverse(board);
|
||||||
Date end = new Date();
|
Date end = new Date();
|
||||||
if (result.board != null) {
|
if (result.board != null) {
|
||||||
long runtime = end.getTime() - start.getTime();
|
long runtime = end.getTime() - start.getTime();
|
||||||
|
|
||||||
timer.add(runtime);
|
timer.add(runtime);
|
||||||
successes++;
|
successes++;
|
||||||
node = result;
|
node = result;
|
||||||
@ -122,7 +124,7 @@ public class Driver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void writeToFile(String name, StringBuffer values) {
|
private static void writeToFile(String name, StringBuffer values) {
|
||||||
URL resourcePath = Driver.class.getResource("/A1/results/" + name + ".txt");
|
URL resourcePath = Driver.class.getResource("/A1/results/AStar.txt");
|
||||||
URI resourceURI = URI.create(resourcePath.toString());
|
URI resourceURI = URI.create(resourcePath.toString());
|
||||||
File resource = new File(resourceURI.getPath());
|
File resource = new File(resourceURI.getPath());
|
||||||
|
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
package Assignments.A1.models;
|
package Assignments.A1.models;
|
||||||
|
|
||||||
import Assignments.A1.models.helper.Move;
|
|
||||||
import Assignments.A1.models.helper.Pair;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -239,6 +236,17 @@ public class Board {
|
|||||||
* Specifies a way of printing out the board with its current state.
|
* Specifies a way of printing out the board with its current state.
|
||||||
* @return the current state formatted.
|
* @return the current state formatted.
|
||||||
*/
|
*/
|
||||||
|
// @Override
|
||||||
|
// public String toString() {
|
||||||
|
// String result = "";
|
||||||
|
// for (int i = 0; i < 9; i++) {
|
||||||
|
// result += pieces[i] + " ";
|
||||||
|
// if ((i+1) % 3 == 0) {
|
||||||
|
// result += "\n";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
String result = pieces[0] + " " + pieces[1] + " " + pieces[2] + "\n"
|
String result = pieces[0] + " " + pieces[1] + " " + pieces[2] + "\n"
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package Assignments.A1.models;
|
package Assignments.A1.models;
|
||||||
|
|
||||||
import Assignments.A1.models.helper.Move;
|
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,7 +9,6 @@ public class BoardNode implements Comparable<BoardNode> {
|
|||||||
public int heuristic, cost, expected;
|
public int heuristic, cost, expected;
|
||||||
public Board board;
|
public Board board;
|
||||||
public List<BoardNode> children;
|
public List<BoardNode> children;
|
||||||
public int depth = -1;
|
|
||||||
|
|
||||||
public BoardNode(Board board, BoardNode parent) {
|
public BoardNode(Board board, BoardNode parent) {
|
||||||
this.board = board;
|
this.board = board;
|
||||||
@ -20,10 +19,6 @@ public class BoardNode implements Comparable<BoardNode> {
|
|||||||
this.children = new ArrayList<>();
|
this.children = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDepth(int depth) {
|
|
||||||
this.depth = depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getActualCost() {
|
private int getActualCost() {
|
||||||
if (this.parent != null) {
|
if (this.parent != null) {
|
||||||
return this.parent.cost + 10;
|
return this.parent.cost + 10;
|
||||||
@ -36,6 +31,7 @@ public class BoardNode implements Comparable<BoardNode> {
|
|||||||
children.add(node);
|
children.add(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private int getHeuristic() {
|
private int getHeuristic() {
|
||||||
int cost = 0;
|
int cost = 0;
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
package Assignments.A1.models.helper;
|
package Assignments.A1.models;
|
||||||
|
|
||||||
import Assignments.A1.models.Board;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to keep track of moves in either a stack or queues.
|
* Used to keep track of moves in either a stack or queues.
|
@ -1,4 +1,4 @@
|
|||||||
package Assignments.A1.models.helper;
|
package Assignments.A1.models;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to pair two points for moves.
|
* Used to pair two points for moves.
|
@ -1,6 +1,4 @@
|
|||||||
package Assignments.A1.models.helper;
|
package Assignments.A1.models;
|
||||||
|
|
||||||
import Assignments.A1.models.Board;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class allows for abstraction and proper representation of a piece of the 8 puzzle.
|
* This class allows for abstraction and proper representation of a piece of the 8 puzzle.
|
@ -1,11 +1,9 @@
|
|||||||
package Assignments.A1.models.helper;
|
package Assignments.A1.models;
|
||||||
|
|
||||||
import Assignments.A1.models.Board;
|
import Assignments.A1.models.Board;
|
||||||
import Assignments.A1.models.BoardNode;
|
import Assignments.A1.models.BoardNode;
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public interface Solver {
|
public interface Solver {
|
||||||
|
|
||||||
BoardNode traverse(Board root);
|
BoardNode traverse(Board board);
|
||||||
}
|
}
|
@ -2,31 +2,24 @@ package Assignments.A1.solving_algorithms;
|
|||||||
|
|
||||||
import Assignments.A1.models.Board;
|
import Assignments.A1.models.Board;
|
||||||
import Assignments.A1.models.BoardNode;
|
import Assignments.A1.models.BoardNode;
|
||||||
import Assignments.A1.models.helper.Move;
|
import Assignments.A1.models.Move;
|
||||||
import Assignments.A1.models.helper.Solver;
|
import Assignments.A1.models.Solver;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.PriorityQueue;
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
public class PriorityTraversal implements Solver {
|
public class AStar implements Solver {
|
||||||
|
|
||||||
private final Board solved = new Board();
|
private final Board solved = new Board();
|
||||||
private final HashSet<Board> visited = new HashSet<>();
|
private final HashSet<Board> visited = new HashSet<>();
|
||||||
|
|
||||||
private final Comparator<BoardNode> comparator;
|
|
||||||
|
|
||||||
public PriorityTraversal(Comparator<BoardNode> type) {
|
|
||||||
this.comparator = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BoardNode traverse(Board root) {
|
public BoardNode traverse(Board root) {
|
||||||
PriorityQueue<BoardNode> boards = new PriorityQueue<>(comparator);
|
PriorityQueue<BoardNode> boards = new PriorityQueue<>(new AStarPriority());
|
||||||
boards.add(new BoardNode(root, null));
|
boards.add(new BoardNode(root, null));
|
||||||
BoardNode node = null;
|
BoardNode node = null;
|
||||||
Board current = new Board(root);
|
Board current = new Board(root);
|
||||||
while (!current.equals(solved) && !boards.isEmpty()) {
|
while (!current.equals(solved)) {
|
||||||
node = boards.poll();
|
node = boards.poll();
|
||||||
current = node.board;
|
current = node.board;
|
||||||
if (visited.contains(node.board)) {
|
if (visited.contains(node.board)) {
|
||||||
@ -45,3 +38,10 @@ public class PriorityTraversal implements Solver {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class AStarPriority implements Comparator<BoardNode> {
|
||||||
|
@Override
|
||||||
|
public int compare(BoardNode o1, BoardNode o2) {
|
||||||
|
return Integer.compare(o1.expected, o2.expected);
|
||||||
|
}
|
||||||
|
}
|
50
src/main/java/Assignments/A1/solving_algorithms/BFS.java
Normal file
50
src/main/java/Assignments/A1/solving_algorithms/BFS.java
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
package Assignments.A1.solving_algorithms;
|
||||||
|
|
||||||
|
import Assignments.A1.models.Board;
|
||||||
|
import Assignments.A1.models.BoardNode;
|
||||||
|
import Assignments.A1.models.Move;
|
||||||
|
import Assignments.A1.models.Solver;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
public class BFS implements Solver {
|
||||||
|
|
||||||
|
private final HashSet<Board> visited = new HashSet<>();
|
||||||
|
private static final Board solved = new Board();
|
||||||
|
|
||||||
|
public BoardNode traverse(Board root) {
|
||||||
|
PriorityQueue<BoardNode> boards = new PriorityQueue<>(new BFSPriority());
|
||||||
|
HashSet<Board> visited = new HashSet<>();
|
||||||
|
boards.add(new BoardNode(root, null));
|
||||||
|
BoardNode node = null;
|
||||||
|
Board current = new Board(root);
|
||||||
|
while (!current.equals(solved)) {
|
||||||
|
node = boards.poll();
|
||||||
|
current = node.board;
|
||||||
|
if (visited.contains(node.board)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
visited.add(node.board);
|
||||||
|
List<Move> children = node.board.getMoves();
|
||||||
|
for (Move move : children) {
|
||||||
|
Board child = new Board(node.board);
|
||||||
|
child.swap(move);
|
||||||
|
BoardNode childNode = new BoardNode(child, node);
|
||||||
|
boards.add(childNode);
|
||||||
|
node.addChild(childNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BFSPriority implements Comparator<BoardNode> {
|
||||||
|
@Override
|
||||||
|
public int compare(BoardNode o1, BoardNode o2) {
|
||||||
|
return Integer.compare(o1.heuristic, o2.heuristic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,43 +1,67 @@
|
|||||||
package Assignments.A1.solving_algorithms;
|
package Assignments.A1.solving_algorithms;
|
||||||
|
|
||||||
import Assignments.A1.models.*;
|
import Assignments.A1.models.Board;
|
||||||
import Assignments.A1.models.helper.Move;
|
import Assignments.A1.models.BoardGenerator;
|
||||||
import Assignments.A1.models.helper.Solver;
|
import Assignments.A1.models.Move;
|
||||||
|
import Assignments.A1.models.Pair;
|
||||||
import Assignments.A1.resources.Parameters;
|
import Assignments.A1.resources.Parameters;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class DFS implements Solver {
|
public class DFS {
|
||||||
|
|
||||||
private final Board solved = new Board();
|
private final Board solved = new Board();
|
||||||
private final List<String> tried = new ArrayList<>();
|
private final List<String> tried = new ArrayList<>();
|
||||||
|
|
||||||
public BoardNode traverse(Board root) {
|
/* Commented out for future reference. */
|
||||||
Stack<BoardNode> stack = new Stack<>();
|
// public Board dfs(Board root, int depth, ArrayList<String> visited) {
|
||||||
BoardNode rootNode = new BoardNode(root, null);
|
// counter++;
|
||||||
rootNode.setDepth(0);
|
// if (root.equals(solved)) {
|
||||||
stack.push(rootNode);
|
// return root;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// ArrayList<String> directParents = new ArrayList<>(visited);
|
||||||
|
// if (depth == Parameters.MAX_DEPTH || visited.contains(root.toString()) || tried.contains(root.toString())) {
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
// directParents.add(root.toString());
|
||||||
|
// tried.add(root.toString());
|
||||||
|
//
|
||||||
|
// List<Move> moves = root.getMoves();
|
||||||
|
// int moveNum = 1;
|
||||||
|
// for (Move next : moves) {
|
||||||
|
//
|
||||||
|
// Board child = next.getBoard();
|
||||||
|
// child.swap(next);
|
||||||
|
// moveNum++;
|
||||||
|
// Board board = dfs(child, depth+1, directParents);
|
||||||
|
// if (board != null) {
|
||||||
|
// return board;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
public Board traverse(Board root, int depth) {
|
||||||
|
Stack<Board> stack = new Stack<>();
|
||||||
|
stack.push(root);
|
||||||
|
|
||||||
while (!stack.isEmpty()) {
|
while (!stack.isEmpty()) {
|
||||||
BoardNode current = stack.pop();
|
Board current = stack.pop();
|
||||||
|
if (current.equals(solved)) {
|
||||||
if (current.board.equals(solved)) {
|
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current.depth > Parameters.MAX_DEPTH || tried.contains(current.toString())) {
|
if (depth == Parameters.MAX_DEPTH || tried.contains(current.toString())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tried.add(current.toString());
|
tried.add(current.toString());
|
||||||
|
|
||||||
List<Move> moves = current.board.getMoves();
|
List<Move> moves = current.getMoves();
|
||||||
for (Move next : moves) {
|
for (Move next : moves) {
|
||||||
Board child = next.getBoard();
|
Board child = next.getBoard();
|
||||||
child.swap(next);
|
child.swap(next);
|
||||||
BoardNode childNode = new BoardNode(child, current);
|
stack.push(child);
|
||||||
childNode.setDepth(current.depth+1);
|
|
||||||
stack.push(childNode);
|
|
||||||
current.addChild(childNode);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
47
src/main/java/Assignments/A1/solving_algorithms/UCS.java
Normal file
47
src/main/java/Assignments/A1/solving_algorithms/UCS.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package Assignments.A1.solving_algorithms;
|
||||||
|
|
||||||
|
import Assignments.A1.models.Board;
|
||||||
|
import Assignments.A1.models.BoardNode;
|
||||||
|
import Assignments.A1.models.Move;
|
||||||
|
import Assignments.A1.models.Solver;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.PriorityQueue;
|
||||||
|
|
||||||
|
public class UCS implements Solver {
|
||||||
|
private final Board solved = new Board();
|
||||||
|
private final HashSet<Board> visited = new HashSet<>();
|
||||||
|
|
||||||
|
public BoardNode traverse(Board root) {
|
||||||
|
PriorityQueue<BoardNode> boards = new PriorityQueue<>(new UCSPriority());
|
||||||
|
boards.add(new BoardNode(root, null));
|
||||||
|
BoardNode node = null;
|
||||||
|
Board current = new Board(root);
|
||||||
|
while (!current.equals(solved)) {
|
||||||
|
node = boards.poll();
|
||||||
|
current = node.board;
|
||||||
|
if (visited.contains(node.board)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
visited.add(node.board);
|
||||||
|
List<Move> children = node.board.getMoves();
|
||||||
|
for (Move move : children) {
|
||||||
|
Board child = new Board(node.board);
|
||||||
|
child.swap(move);
|
||||||
|
BoardNode childNode = new BoardNode(child, node);
|
||||||
|
boards.add(childNode);
|
||||||
|
node.addChild(childNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class UCSPriority implements Comparator<BoardNode> {
|
||||||
|
@Override
|
||||||
|
public int compare(BoardNode o1, BoardNode o2) {
|
||||||
|
return Integer.compare(o1.cost, o2.cost);
|
||||||
|
}
|
||||||
|
}
|
@ -1,13 +0,0 @@
|
|||||||
package Assignments.A1.solving_algorithms.comparators;
|
|
||||||
|
|
||||||
import Assignments.A1.models.Board;
|
|
||||||
import Assignments.A1.models.BoardNode;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public class AStar implements Comparator<BoardNode> {
|
|
||||||
@Override
|
|
||||||
public int compare(BoardNode o1, BoardNode o2) {
|
|
||||||
return Integer.compare(o1.expected, o2.expected);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
package Assignments.A1.solving_algorithms.comparators;
|
|
||||||
|
|
||||||
import Assignments.A1.models.BoardNode;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public class BFS implements Comparator<BoardNode> {
|
|
||||||
@Override
|
|
||||||
public int compare(BoardNode o1, BoardNode o2) {
|
|
||||||
return Integer.compare(o1.heuristic, o2.heuristic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
|||||||
package Assignments.A1.solving_algorithms.comparators;
|
|
||||||
|
|
||||||
import Assignments.A1.models.BoardNode;
|
|
||||||
|
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
public class UCS implements Comparator<BoardNode> {
|
|
||||||
@Override
|
|
||||||
public int compare(BoardNode o1, BoardNode o2) {
|
|
||||||
return Integer.compare(o1.cost, o2.cost);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,11 +1,12 @@
|
|||||||
package Assignments.A1.view;
|
package Assignments.A1.view;
|
||||||
|
|
||||||
import Assignments.A1.models.Board;
|
|
||||||
import Assignments.A1.models.BoardNode;
|
import Assignments.A1.models.BoardNode;
|
||||||
import javafx.event.ActionEvent;
|
import javafx.event.ActionEvent;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
|
|
||||||
|
import javax.swing.tree.TreeNode;
|
||||||
|
|
||||||
public class BoardViewCodeBehind {
|
public class BoardViewCodeBehind {
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
@ -14,23 +15,14 @@ public class BoardViewCodeBehind {
|
|||||||
@FXML
|
@FXML
|
||||||
private Label current_board;
|
private Label current_board;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private Label alg_speed;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Button generate_board;
|
private Button generate_board;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private Label disclaimer;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private MenuButton menu_alg;
|
private MenuButton menu_alg;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private ToggleButton expanded;
|
private ToggleButton showSolvedPath;
|
||||||
|
|
||||||
@FXML
|
|
||||||
private ToggleButton showOnlySolvedPath;
|
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private MenuItem AStar;
|
private MenuItem AStar;
|
||||||
@ -47,6 +39,9 @@ public class BoardViewCodeBehind {
|
|||||||
@FXML
|
@FXML
|
||||||
private Button solve_button;
|
private Button solve_button;
|
||||||
|
|
||||||
|
@FXML
|
||||||
|
private ProgressBar solving_prog;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private Label gen_board_err;
|
private Label gen_board_err;
|
||||||
|
|
||||||
@ -68,11 +63,8 @@ public class BoardViewCodeBehind {
|
|||||||
this.AStar.disableProperty().bindBidirectional(viewModel.AStarProperty());
|
this.AStar.disableProperty().bindBidirectional(viewModel.AStarProperty());
|
||||||
this.gen_board_err.visibleProperty().bindBidirectional(viewModel.genBoardErrProperty());
|
this.gen_board_err.visibleProperty().bindBidirectional(viewModel.genBoardErrProperty());
|
||||||
this.no_solv_alg_err.visibleProperty().bindBidirectional(viewModel.solvingAlgErrProperty());
|
this.no_solv_alg_err.visibleProperty().bindBidirectional(viewModel.solvingAlgErrProperty());
|
||||||
this.expanded.selectedProperty().bindBidirectional(viewModel.expandedProperty());
|
|
||||||
this.alg_speed.textProperty().bindBidirectional(viewModel.algSpeedProperty());
|
|
||||||
this.disclaimer.visibleProperty().bindBidirectional(viewModel.disclaimerProperty());
|
|
||||||
|
|
||||||
this.current_board.textProperty().setValue(new Board().toString());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onGenerateBoard(ActionEvent actionEvent) {
|
public void onGenerateBoard(ActionEvent actionEvent) {
|
||||||
@ -80,16 +72,11 @@ public class BoardViewCodeBehind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void showSolvedPath(ActionEvent actionEvent) {
|
public void showSolvedPath(ActionEvent actionEvent) {
|
||||||
if (this.viewModel.getSolvedRootNode() != null) {
|
|
||||||
this.viewModel.updateDisplay();
|
|
||||||
}
|
|
||||||
this.spanning_tree.setRoot(viewModel.getSolvedRootNode());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSolveButton(ActionEvent actionEvent) {
|
public void onSolveButton(ActionEvent actionEvent) {
|
||||||
viewModel.solveBoard();
|
viewModel.solveBoard();
|
||||||
viewModel.updateDisplay();
|
|
||||||
this.spanning_tree.setRoot(new TreeItem<>());
|
|
||||||
this.spanning_tree.setRoot(viewModel.getSolvedRootNode());
|
this.spanning_tree.setRoot(viewModel.getSolvedRootNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,33 +3,32 @@ package Assignments.A1.view;
|
|||||||
import Assignments.A1.models.Board;
|
import Assignments.A1.models.Board;
|
||||||
import Assignments.A1.models.BoardGenerator;
|
import Assignments.A1.models.BoardGenerator;
|
||||||
import Assignments.A1.models.BoardNode;
|
import Assignments.A1.models.BoardNode;
|
||||||
import Assignments.A1.models.helper.Solver;
|
import Assignments.A1.models.Solver;
|
||||||
import Assignments.A1.solving_algorithms.PriorityTraversal;
|
import Assignments.A1.solving_algorithms.AStar;
|
||||||
import Assignments.A1.solving_algorithms.comparators.AStar;
|
import Assignments.A1.solving_algorithms.BFS;
|
||||||
import Assignments.A1.solving_algorithms.comparators.BFS;
|
import Assignments.A1.solving_algorithms.UCS;
|
||||||
import Assignments.A1.solving_algorithms.DFS;
|
|
||||||
import Assignments.A1.solving_algorithms.comparators.UCS;
|
|
||||||
import javafx.beans.property.*;
|
import javafx.beans.property.*;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
import javafx.scene.control.TreeItem;
|
import javafx.scene.control.TreeItem;
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
public class MainViewModel {
|
public class MainViewModel {
|
||||||
|
|
||||||
private StringProperty currentBoardProperty, algSpeedProperty;
|
private StringProperty currentBoardProperty, algSpeedProperty;
|
||||||
private BooleanProperty expanded, DFS, UCS, BFS, AStar, solvingAlgErr, genBoardErr, disclaimer;
|
private BooleanProperty showSolvedPath, DFS, UCS, BFS, AStar, solvingAlgErr, genBoardErr;
|
||||||
|
private DoubleProperty solvingProgressProperty;
|
||||||
private String selectedAlg;
|
private String selectedAlg;
|
||||||
|
private final ObservableList<BoardNode> spanningTree = FXCollections.observableArrayList();
|
||||||
|
private final ObjectProperty<ObservableList<BoardNode>> spanningTreeProperty = new SimpleObjectProperty<>(spanningTree);
|
||||||
|
|
||||||
private BoardNode current = new BoardNode(new Board(), null);
|
private BoardNode current = new BoardNode(new Board(), null);
|
||||||
private TreeItem<BoardNode> solvedRootNode = null;
|
private TreeItem<BoardNode> solvedRootNode = null;
|
||||||
private BoardNode solvedRootBoardNode = null;
|
|
||||||
|
|
||||||
public MainViewModel() {
|
public MainViewModel() {
|
||||||
this.currentBoardProperty = new SimpleStringProperty();
|
this.currentBoardProperty = new SimpleStringProperty();
|
||||||
this.algSpeedProperty = new SimpleStringProperty();
|
this.algSpeedProperty = new SimpleStringProperty();
|
||||||
this.disclaimer = new SimpleBooleanProperty();
|
this.showSolvedPath = new SimpleBooleanProperty();
|
||||||
this.expanded = new SimpleBooleanProperty();
|
this.solvingProgressProperty = new SimpleDoubleProperty();
|
||||||
this.DFS = new SimpleBooleanProperty();
|
this.DFS = new SimpleBooleanProperty();
|
||||||
this.UCS = new SimpleBooleanProperty();
|
this.UCS = new SimpleBooleanProperty();
|
||||||
this.BFS = new SimpleBooleanProperty();
|
this.BFS = new SimpleBooleanProperty();
|
||||||
@ -51,8 +50,6 @@ public class MainViewModel {
|
|||||||
this.UCS.set(value.equals("UCS"));
|
this.UCS.set(value.equals("UCS"));
|
||||||
this.BFS.set(value.equals("BFS"));
|
this.BFS.set(value.equals("BFS"));
|
||||||
this.AStar.set(value.equals("AStar"));
|
this.AStar.set(value.equals("AStar"));
|
||||||
|
|
||||||
this.disclaimer.setValue(value.equals("DFS"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public StringProperty getCurrentBoardProperty() {
|
public StringProperty getCurrentBoardProperty() {
|
||||||
@ -78,40 +75,35 @@ public class MainViewModel {
|
|||||||
|
|
||||||
Solver solver = null;
|
Solver solver = null;
|
||||||
if (DFS.getValue()) {
|
if (DFS.getValue()) {
|
||||||
solver = new DFS();
|
// solver = new DFS();
|
||||||
} else if (UCS.getValue()) {
|
} else if (UCS.getValue()) {
|
||||||
solver = new PriorityTraversal(new UCS());
|
solver = new UCS();
|
||||||
} else if (BFS.getValue()) {
|
} else if (BFS.getValue()) {
|
||||||
solver = new PriorityTraversal(new BFS());
|
solver = new BFS();
|
||||||
} else if (AStar.getValue()) {
|
} else if (AStar.getValue()) {
|
||||||
solver = new PriorityTraversal(new AStar());
|
solver = new AStar();
|
||||||
}
|
}
|
||||||
Date start = new Date();
|
|
||||||
BoardNode solved = solver.traverse(this.current.board);
|
BoardNode solved = solver.traverse(this.current.board);
|
||||||
Date end = new Date();
|
|
||||||
long runtime = end.getTime() - start.getTime();
|
|
||||||
this.algSpeedProperty.setValue(String.valueOf(runtime));
|
|
||||||
|
|
||||||
currentBoardProperty.setValue(solved.board.toString());
|
currentBoardProperty.setValue(solved.board.toString());
|
||||||
BoardNode root = solved;
|
BoardNode root = solved;
|
||||||
while (root.parent != null) {
|
while (root.parent != null) {
|
||||||
root = root.parent;
|
root = root.parent;
|
||||||
}
|
}
|
||||||
this.solvedRootNode = rebuildTree(root, this.expanded.getValue());
|
this.solvedRootNode = rebuildTree(root);
|
||||||
this.solvedRootBoardNode = root;
|
|
||||||
this.current = solved;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateDisplay() {
|
|
||||||
TreeItem<BoardNode> newRoot = null;
|
|
||||||
newRoot = this.rebuildTree(this.solvedRootBoardNode, this.expanded.getValue());
|
|
||||||
this.solvedRootNode = newRoot;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TreeItem<BoardNode> getSolvedRootNode() {
|
public TreeItem<BoardNode> getSolvedRootNode() {
|
||||||
return solvedRootNode;
|
return solvedRootNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ObservableList<BoardNode> getSpanningTree() {
|
||||||
|
return spanningTreeProperty.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectProperty<ObservableList<BoardNode>> spanningTreeProperty() {
|
||||||
|
return spanningTreeProperty;
|
||||||
|
}
|
||||||
|
|
||||||
public BooleanProperty DFSProperty() {
|
public BooleanProperty DFSProperty() {
|
||||||
return DFS;
|
return DFS;
|
||||||
}
|
}
|
||||||
@ -136,60 +128,17 @@ public class MainViewModel {
|
|||||||
return genBoardErr;
|
return genBoardErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TreeItem<BoardNode> rebuildTree(BoardNode root, boolean expanded) {
|
public TreeItem<BoardNode> rebuildTree(BoardNode root) {
|
||||||
if (this.selectedAlg != null) {
|
TreeItem<BoardNode> treeItem = new TreeItem<>(root);
|
||||||
if (this.selectedAlg.equals("DFS")) {
|
|
||||||
Stack<BoardNode> generations = new Stack<>();
|
|
||||||
BoardNode temp = this.current;
|
|
||||||
while (temp != null) {
|
|
||||||
generations.push(temp);
|
|
||||||
temp = temp.parent;
|
|
||||||
}
|
|
||||||
TreeItem<BoardNode> rootItem = new TreeItem<>(root);
|
|
||||||
TreeItem<BoardNode> currItem = rootItem;
|
|
||||||
while (!generations.isEmpty()) {
|
|
||||||
TreeItem<BoardNode> child = new TreeItem<>(generations.pop());
|
|
||||||
currItem.getChildren().add(child);
|
|
||||||
currItem.setExpanded(expanded);
|
|
||||||
currItem = child;
|
|
||||||
}
|
|
||||||
return rootItem;
|
|
||||||
} else {
|
|
||||||
TreeItem<BoardNode> treeItem = new TreeItem<>(root);
|
|
||||||
for (BoardNode child : root.children) {
|
|
||||||
TreeItem<BoardNode> childItem = rebuildTree(child, expanded);
|
|
||||||
treeItem.getChildren().add(childItem);
|
|
||||||
}
|
|
||||||
treeItem.setExpanded(expanded);
|
|
||||||
|
|
||||||
return treeItem;
|
// Recursively create TreeItems for child nodes
|
||||||
}
|
for (BoardNode child : root.children) {
|
||||||
|
TreeItem<BoardNode> childItem = rebuildTree(child);
|
||||||
|
treeItem.getChildren().add(childItem);
|
||||||
}
|
}
|
||||||
return new TreeItem<>();
|
|
||||||
|
return treeItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public boolean getExpanded() {
|
|
||||||
return expanded.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BooleanProperty expandedProperty() {
|
|
||||||
return expanded;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getAlgSpeedProperty() {
|
|
||||||
return algSpeedProperty.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public StringProperty algSpeedProperty() {
|
|
||||||
return algSpeedProperty;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isDisclaimer() {
|
|
||||||
return disclaimer.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public BooleanProperty disclaimerProperty() {
|
|
||||||
return disclaimer;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.control.Menu?>
|
||||||
|
<?import javafx.scene.control.MenuBar?>
|
||||||
<?import javafx.scene.control.MenuButton?>
|
<?import javafx.scene.control.MenuButton?>
|
||||||
<?import javafx.scene.control.MenuItem?>
|
<?import javafx.scene.control.MenuItem?>
|
||||||
|
<?import javafx.scene.control.ProgressBar?>
|
||||||
<?import javafx.scene.control.ToggleButton?>
|
<?import javafx.scene.control.ToggleButton?>
|
||||||
<?import javafx.scene.control.TreeView?>
|
<?import javafx.scene.control.TreeView?>
|
||||||
<?import javafx.scene.layout.Pane?>
|
<?import javafx.scene.layout.Pane?>
|
||||||
@ -11,10 +14,30 @@
|
|||||||
|
|
||||||
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="591.0" prefWidth="928.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Assignments.A1.view.BoardViewCodeBehind">
|
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="591.0" prefWidth="928.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Assignments.A1.view.BoardViewCodeBehind">
|
||||||
<children>
|
<children>
|
||||||
|
<MenuBar layoutY="2.0" prefHeight="25.0" prefWidth="134.0">
|
||||||
|
<menus>
|
||||||
|
<Menu mnemonicParsing="false" text="File">
|
||||||
|
<items>
|
||||||
|
<MenuItem mnemonicParsing="false" text="Close" />
|
||||||
|
</items>
|
||||||
|
</Menu>
|
||||||
|
<Menu mnemonicParsing="false" text="Edit">
|
||||||
|
<items>
|
||||||
|
<MenuItem mnemonicParsing="false" text="Delete" />
|
||||||
|
</items>
|
||||||
|
</Menu>
|
||||||
|
<Menu mnemonicParsing="false" text="Help">
|
||||||
|
<items>
|
||||||
|
<MenuItem mnemonicParsing="false" text="About" />
|
||||||
|
</items>
|
||||||
|
</Menu>
|
||||||
|
</menus>
|
||||||
|
</MenuBar>
|
||||||
<TreeView fx:id="spanning_tree" layoutX="334.0" layoutY="67.0" prefHeight="416.0" prefWidth="532.0" />
|
<TreeView fx:id="spanning_tree" layoutX="334.0" layoutY="67.0" prefHeight="416.0" prefWidth="532.0" />
|
||||||
<ToggleButton fx:id="expanded" layoutX="547.0" layoutY="33.0" mnemonicParsing="false" onAction="#showSolvedPath" text="Expand Directory" />
|
<ToggleButton fx:id="showSolvedPath" layoutX="545.0" layoutY="34.0" mnemonicParsing="false" onAction="#showSolvedPath" text="Show Solved Path" />
|
||||||
|
<ProgressBar id="solve_board_progress" fx:id="solving_prog" layoutX="500.0" layoutY="538.0" mouseTransparent="true" prefWidth="200.0" progress="0.0" />
|
||||||
<Button id="generate_board" fx:id="generate_board" layoutX="97.0" layoutY="367.0" mnemonicParsing="false" onAction="#onGenerateBoard" text="Generate Random Board" />
|
<Button id="generate_board" fx:id="generate_board" layoutX="97.0" layoutY="367.0" mnemonicParsing="false" onAction="#onGenerateBoard" text="Generate Random Board" />
|
||||||
<Label fx:id="current_board" alignment="CENTER" layoutX="104.0" layoutY="129.0" prefHeight="184.0" prefWidth="134.0" textAlignment="JUSTIFY" wrapText="true">
|
<Label fx:id="current_board" alignment="CENTER" layoutX="104.0" layoutY="129.0" prefHeight="184.0" prefWidth="134.0" text="0 1 2 8 0 4 7 6 5" textAlignment="JUSTIFY" wrapText="true">
|
||||||
<font>
|
<font>
|
||||||
<Font size="41.0" />
|
<Font size="41.0" />
|
||||||
</font>
|
</font>
|
||||||
@ -29,7 +52,7 @@
|
|||||||
</items>
|
</items>
|
||||||
</MenuButton>
|
</MenuButton>
|
||||||
<Label layoutX="728.0" layoutY="507.0" text="Algorithm Speed (ms): " />
|
<Label layoutX="728.0" layoutY="507.0" text="Algorithm Speed (ms): " />
|
||||||
<Label fx:id="alg_speed" layoutX="849.0" layoutY="507.0" text="0" />
|
<Label layoutX="849.0" layoutY="507.0" text="0" />
|
||||||
<Label fx:id="gen_board_err" layoutX="37.0" layoutY="525.0" prefHeight="26.0" prefWidth="325.0" text="You must generate a board before solving" textFill="RED" visible="false">
|
<Label fx:id="gen_board_err" layoutX="37.0" layoutY="525.0" prefHeight="26.0" prefWidth="325.0" text="You must generate a board before solving" textFill="RED" visible="false">
|
||||||
<font>
|
<font>
|
||||||
<Font size="17.0" />
|
<Font size="17.0" />
|
||||||
@ -40,6 +63,5 @@
|
|||||||
<Font size="14.0" />
|
<Font size="14.0" />
|
||||||
</font>
|
</font>
|
||||||
</Label>
|
</Label>
|
||||||
<Label fx:id="disclaimer" layoutX="176.0" layoutY="541.0" prefHeight="42.0" prefWidth="558.0" text="**Note: If traversing with DFS, it only shows the solving directory to prevent JavaFX StackOverflow.** However, the traversal algorithm and algorithm speed does explore all nodes despite directory display." textAlignment="CENTER" wrapText="true" />
|
|
||||||
</children>
|
</children>
|
||||||
</Pane>
|
</Pane>
|
||||||
|
Loading…
Reference in New Issue
Block a user