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.Board;
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.
@ -21,13 +24,19 @@ import Assignments.A1.models.Piece;
public class Driver {
public static void main(String[] args) {
Board board = BoardGenerator.generateBoard();
System.out.println(board);
System.out.println(BoardGenerator.isSolvable(board));
Board goal = new Board();
System.out.println(goal);
System.out.println(BoardGenerator.isSolvable(goal));
DFS solver = new DFS();
// Board board = new Board();
// Board result = solver.dfs(board, 0);
// System.out.println(result);
// Board board = BoardGenerator.generateBoard();
//
// 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 {
private int[] pieces;
public int[] pieces;
/**
* Default constructor that generates the solved board.
@ -108,12 +108,17 @@ public class Board {
* @return the location of the empty piece.
*/
public int getOpenLocation() {
int loc = -1;
for (int index = 0; index < 9; index++) {
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;
}
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.
*
@ -164,17 +176,17 @@ public class Board {
int row = 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) {
moves.add(new Move(space, space-3));
moves.add(new Move(space, space-1, this));
}
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;
}
@ -217,26 +229,29 @@ public class Board {
return false;
}
Board other = (Board) o;
for (int curr : this.pieces) {
if (curr != other.pieces[curr]) {
return false;
}
}
return true;
return (other.toString().equals(this.toString()));
}
/**
* Specifies a way of printing out the board with its current state.
* @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
public String toString() {
String result = "";
for (int i = 0; i < 9; i++) {
result += pieces[i] + " ";
if ((i+1) % 3 == 0) {
result += "\n";
}
}
return result;
}

View File

@ -70,17 +70,17 @@ public class BoardGenerator {
// Holds the number of inversions
int inversions = 0;
int[] ordered = board.getPieces();
int[] ordered = board.pieces;
// Counts the number of inversions
for (int index = 0; index < 8; index++) {
for (int invers = index+1; invers < 8; invers++) {
for (int index = 0; index < 9; index++) {
for (int invers = index+1; invers < 9; invers++) {
if (ordered[index] > ordered[invers]) {
inversions++;
}
}
}
return (inversions % 2 == 1);
return (inversions % 2 == 0);
}

View File

@ -19,9 +19,11 @@ public class Move {
* @postcondition a new move is created.
* @param firstpoint the first 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.board = new Board(root);
}
/**
@ -45,5 +47,28 @@ public class Move {
used = true;
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 {
/* 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;
import Assignments.A1.models.Board;
import Assignments.A1.models.BoardGenerator;
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.HashSet;
import java.util.Stack;
import java.util.*;
public class DFS {
private HashSet<Board> visited = new HashSet<>();
private HashMap<Board, Stack<Move>> moves = new HashMap<>();
private int counter = 0;
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;
}
}