Still development of DFS, nonfunctional. Pushing to access on other device.
This commit is contained in:
parent
8ecead1b37
commit
687eb8964b
@ -6,6 +6,9 @@ package Assignments.A1;
|
|||||||
import Assignments.A1.models.BoardGenerator;
|
import Assignments.A1.models.BoardGenerator;
|
||||||
import Assignments.A1.models.Board;
|
import Assignments.A1.models.Board;
|
||||||
import Assignments.A1.models.Piece;
|
import Assignments.A1.models.Piece;
|
||||||
|
import Assignments.A1.solving_algorithms.DFS;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Board will be used to save locations in a 2D array.
|
* Board will be used to save locations in a 2D array.
|
||||||
@ -21,13 +24,19 @@ import Assignments.A1.models.Piece;
|
|||||||
public class Driver {
|
public class Driver {
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
Board board = BoardGenerator.generateBoard();
|
DFS solver = new DFS();
|
||||||
System.out.println(board);
|
// Board board = new Board();
|
||||||
System.out.println(BoardGenerator.isSolvable(board));
|
// Board result = solver.dfs(board, 0);
|
||||||
|
// System.out.println(result);
|
||||||
Board goal = new Board();
|
// Board board = BoardGenerator.generateBoard();
|
||||||
System.out.println(goal);
|
//
|
||||||
System.out.println(BoardGenerator.isSolvable(goal));
|
// Board result = solver.dfs(board, 0, new ArrayList<String>());
|
||||||
|
// System.out.println(result);
|
||||||
|
//
|
||||||
|
int[] temp = {0,8,3,5,1,6,4,7,2};
|
||||||
|
Board solvable = new Board(temp);
|
||||||
|
Board result = solver.dfs(solvable,0, new ArrayList<>());
|
||||||
|
System.out.println(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class Board {
|
public class Board {
|
||||||
|
|
||||||
private int[] pieces;
|
public int[] pieces;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor that generates the solved board.
|
* Default constructor that generates the solved board.
|
||||||
@ -108,13 +108,18 @@ public class Board {
|
|||||||
* @return the location of the empty piece.
|
* @return the location of the empty piece.
|
||||||
*/
|
*/
|
||||||
public int getOpenLocation() {
|
public int getOpenLocation() {
|
||||||
|
int loc = -1;
|
||||||
for (int index = 0; index < 9; index++) {
|
for (int index = 0; index < 9; index++) {
|
||||||
if (this.pieces[index] == 0) {
|
if (this.pieces[index] == 0) {
|
||||||
return index;
|
loc = index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (loc != -1) {
|
||||||
|
return loc;
|
||||||
|
} else {
|
||||||
throw new IllegalStateException("The state of the board must have 1 empty space.");
|
throw new IllegalStateException("The state of the board must have 1 empty space.");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Takes two values on the board and swaps them.
|
* Takes two values on the board and swaps them.
|
||||||
@ -131,6 +136,13 @@ public class Board {
|
|||||||
this.pieces[second] = temp;
|
this.pieces[second] = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void swap(Move move) {
|
||||||
|
Pair<Integer> points = move.traverse();
|
||||||
|
int temp = this.pieces[points.first];
|
||||||
|
this.pieces[points.first] = this.pieces[points.second];
|
||||||
|
this.pieces[points.second] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the pieces in order in a single array of size 8.
|
* Gets the pieces in order in a single array of size 8.
|
||||||
*
|
*
|
||||||
@ -164,17 +176,17 @@ public class Board {
|
|||||||
int row = space / 3;
|
int row = space / 3;
|
||||||
int column = space % 3;
|
int column = space % 3;
|
||||||
|
|
||||||
if (row > 0) {
|
|
||||||
moves.add(new Move(space, space-1));
|
|
||||||
}
|
|
||||||
if (row < 2) {
|
|
||||||
moves.add(new Move(space, space+1));
|
|
||||||
}
|
|
||||||
if (column > 0) {
|
if (column > 0) {
|
||||||
moves.add(new Move(space, space-3));
|
moves.add(new Move(space, space-1, this));
|
||||||
}
|
}
|
||||||
if (column < 2) {
|
if (column < 2) {
|
||||||
moves.add(new Move(space, space+3));
|
moves.add(new Move(space, space+1, this));
|
||||||
|
}
|
||||||
|
if (row > 0) {
|
||||||
|
moves.add(new Move(space, space-3, this));
|
||||||
|
}
|
||||||
|
if (row < 2) {
|
||||||
|
moves.add(new Move(space, space+3, this));
|
||||||
}
|
}
|
||||||
return moves;
|
return moves;
|
||||||
}
|
}
|
||||||
@ -217,26 +229,29 @@ public class Board {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Board other = (Board) o;
|
Board other = (Board) o;
|
||||||
for (int curr : this.pieces) {
|
return (other.toString().equals(this.toString()));
|
||||||
if (curr != other.pieces[curr]) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 = "";
|
String result = "";
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
result += pieces[i] + " ";
|
result += pieces[i] + " ";
|
||||||
if ((i+1) % 3 == 0) {
|
|
||||||
result += "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -70,17 +70,17 @@ public class BoardGenerator {
|
|||||||
|
|
||||||
// Holds the number of inversions
|
// Holds the number of inversions
|
||||||
int inversions = 0;
|
int inversions = 0;
|
||||||
int[] ordered = board.getPieces();
|
int[] ordered = board.pieces;
|
||||||
|
|
||||||
// Counts the number of inversions
|
// Counts the number of inversions
|
||||||
for (int index = 0; index < 8; index++) {
|
for (int index = 0; index < 9; index++) {
|
||||||
for (int invers = index+1; invers < 8; invers++) {
|
for (int invers = index+1; invers < 9; invers++) {
|
||||||
if (ordered[index] > ordered[invers]) {
|
if (ordered[index] > ordered[invers]) {
|
||||||
inversions++;
|
inversions++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (inversions % 2 == 1);
|
return (inversions % 2 == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,9 +19,11 @@ public class Move {
|
|||||||
* @postcondition a new move is created.
|
* @postcondition a new move is created.
|
||||||
* @param firstpoint the first point
|
* @param firstpoint the first point
|
||||||
* @param secondpoint the second point
|
* @param secondpoint the second point
|
||||||
|
* @param root the board attached to the move.
|
||||||
*/
|
*/
|
||||||
public Move(int firstpoint, int secondpoint) {
|
public Move(int firstpoint, int secondpoint, Board root) {
|
||||||
this.points = new Pair<>(firstpoint, secondpoint);
|
this.points = new Pair<>(firstpoint, secondpoint);
|
||||||
|
this.board = new Board(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -45,5 +47,28 @@ public class Move {
|
|||||||
used = true;
|
used = true;
|
||||||
return points;
|
return points;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the board for the move.
|
||||||
|
*
|
||||||
|
* @precondition none
|
||||||
|
* @postcondition none
|
||||||
|
* @return the board.
|
||||||
|
*/
|
||||||
|
public Board getBoard() {
|
||||||
|
return this.board;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as root
|
||||||
|
*/
|
||||||
|
public boolean isRoot() {
|
||||||
|
Board temp = new Board(this.board);
|
||||||
|
temp.swap(this.points.first, this.points.second);
|
||||||
|
if (temp.equals(this.board)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,6 @@ package Assignments.A1.resources;
|
|||||||
public class Parameters {
|
public class Parameters {
|
||||||
|
|
||||||
/* Used to prevent DFS from going down only 1 branch */
|
/* Used to prevent DFS from going down only 1 branch */
|
||||||
public static final int MAX_DEPTH = 40; // Max number of moves in 8-Puzzle's are 31 moves if solvable.
|
public static final int MAX_DEPTH = 31; // Max number of moves in 8-Puzzle's are 31 moves if solvable.
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,47 @@
|
|||||||
package Assignments.A1.solving_algorithms;
|
package Assignments.A1.solving_algorithms;
|
||||||
|
|
||||||
import Assignments.A1.models.Board;
|
import Assignments.A1.models.Board;
|
||||||
|
import Assignments.A1.models.BoardGenerator;
|
||||||
import Assignments.A1.models.Move;
|
import Assignments.A1.models.Move;
|
||||||
|
import Assignments.A1.models.Pair;
|
||||||
|
import Assignments.A1.resources.Parameters;
|
||||||
|
import org.junit.experimental.theories.internal.ParameterizedAssertionError;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Stack;
|
|
||||||
|
|
||||||
public class DFS {
|
public class DFS {
|
||||||
|
|
||||||
private HashSet<Board> visited = new HashSet<>();
|
private int counter = 0;
|
||||||
private HashMap<Board, Stack<Move>> moves = new HashMap<>();
|
private final Board solved = new Board();
|
||||||
|
private List<String> tried = new ArrayList<>();
|
||||||
|
|
||||||
public void dfs(Board root) {
|
public Board dfs(Board root, int depth, ArrayList<String> visited) {
|
||||||
|
counter++;
|
||||||
|
System.out.println("Num of boards " + counter + " | Depth " + depth);
|
||||||
|
if (root.equals(solved)) {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user