Still development of DFS, nonfunctional. Pushing to access on other device.

This commit is contained in:
Jonathan Turner 2024-02-05 18:50:29 -05:00
parent 8ecead1b37
commit 687eb8964b
6 changed files with 115 additions and 39 deletions

View File

@ -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);
} }
} }

View File

@ -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,12 +108,17 @@ 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;
} }
} }
throw new IllegalStateException("The state of the board must have 1 empty space."); if (loc != -1) {
return loc;
} else {
throw new IllegalStateException("The state of the board must have 1 empty space.");
}
} }
/** /**
@ -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;
} }

View File

@ -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);
} }

View File

@ -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;
}
} }

View File

@ -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.
} }

View File

@ -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;
} }
} }