Added functionality to allow for a board to be generated and check if the board is solvable.
This commit is contained in:
parent
945ef8fff6
commit
e98ad869e8
@ -3,6 +3,10 @@ package Assignments.A1;
|
||||
// Potentially will be changed to an UI Implementation with JavaFX if time permits.
|
||||
|
||||
|
||||
import Assignments.A1.managers.BoardGenerator;
|
||||
import Assignments.A1.models.Board;
|
||||
import Assignments.A1.models.Piece;
|
||||
|
||||
/**
|
||||
* Board will be used to save locations in a 2D array.
|
||||
*
|
||||
@ -16,6 +20,24 @@ package Assignments.A1;
|
||||
*/
|
||||
public class Driver {
|
||||
|
||||
public static void main(String[] args) {
|
||||
Board board = BoardGenerator.generateBoard();
|
||||
System.out.println(board);
|
||||
System.out.println(BoardGenerator.isSolvable(board));
|
||||
|
||||
Piece[] pieces = new Piece[9];
|
||||
pieces[0] = new Piece(0,7);
|
||||
pieces[1] = null;
|
||||
pieces[2] = new Piece(2,5);
|
||||
pieces[3] = new Piece(3,1);
|
||||
pieces[4] = new Piece(4,2);
|
||||
pieces[5] = new Piece(5,4);
|
||||
pieces[6] = new Piece(6,6);
|
||||
pieces[7] = new Piece(7,3);
|
||||
pieces[8] = new Piece(8,8);
|
||||
|
||||
board = new Board(pieces);
|
||||
System.out.println(BoardGenerator.isSolvable(board));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,95 @@
|
||||
package Assignments.A1.managers;
|
||||
|
||||
import Assignments.A1.models.Board;
|
||||
import Assignments.A1.models.Piece;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class is used to create and check boards.
|
||||
*
|
||||
* @author Jonathan Turner
|
||||
* @version Spring 2024
|
||||
*/
|
||||
public class BoardGenerator {
|
||||
|
||||
/**
|
||||
* Generates a random 8-Puzzle that is always solvable.
|
||||
*
|
||||
* @precondition none
|
||||
* @postcondition none
|
||||
*
|
||||
* @return a board that is solvable.
|
||||
*/
|
||||
public static Board generateBoard() {
|
||||
|
||||
Integer[] values = {1, 2, 3, 4, 5, 6, 7, 8};
|
||||
List<Integer> random = new ArrayList<>(Arrays.asList(values));
|
||||
Collections.shuffle(random);
|
||||
|
||||
Random gen = new Random();
|
||||
int spaceLoc = gen.nextInt(9);
|
||||
Piece[] pieces = new Piece[9];
|
||||
for (int curr = 0; curr < values.length; curr++) {
|
||||
if (curr < spaceLoc) {
|
||||
pieces[curr] = new Piece(curr,random.get(curr));
|
||||
} else {
|
||||
pieces[curr+1] = new Piece(curr+1,random.get(curr));
|
||||
}
|
||||
}
|
||||
|
||||
// Checks if the board is solveable.
|
||||
Board generated = new Board(pieces);
|
||||
if (isSolvable(generated)) {
|
||||
return generated;
|
||||
} else { // If not it swaps the last two values (ignoring the space)
|
||||
if (spaceLoc == 8) {
|
||||
pieces[7].setLocation(6);
|
||||
pieces[6].setLocation(7);
|
||||
} else if (spaceLoc == 7) {
|
||||
pieces[8].setLocation(6);
|
||||
pieces[6].setLocation(8);
|
||||
} else {
|
||||
pieces[7].setLocation(6);
|
||||
pieces[6].setLocation(7);
|
||||
}
|
||||
generated = new Board(pieces);
|
||||
}
|
||||
|
||||
// Puzzle is now solvable.
|
||||
return generated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the board is solvable by checking the number of inversions.
|
||||
* If the number of inversions is even, it is solvable, if not it is not solvable.
|
||||
*
|
||||
* @precondition board != null
|
||||
* @postcondition none
|
||||
*
|
||||
* @param board the board being checked
|
||||
* @return if the board has even inversion, True
|
||||
* if not, False
|
||||
*/
|
||||
public static boolean isSolvable(Board board) {
|
||||
if (board == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Holds the number of inversions
|
||||
int inversions = 0;
|
||||
Piece[] ordered = board.getPiecesInOrder();
|
||||
|
||||
// Counts the number of inversions
|
||||
for (int index = 0; index < 8; index++) {
|
||||
for (int invers = index+1; invers < 8; invers++) {
|
||||
if (ordered[index].getValue() > ordered[invers].getValue()) {
|
||||
inversions++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (inversions % 2 == 0);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package Assignments.A1.models;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* This class keeps track of the current state (whether in permutation or not) of the board.
|
||||
@ -45,6 +46,21 @@ public class Board {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used to create a board with a pre-provided piece list.
|
||||
*
|
||||
* @precondition pieces == 9
|
||||
* @postcondition a board is created with given locations
|
||||
*
|
||||
* @param pieces the provided state.
|
||||
*/
|
||||
public Board(Piece[] pieces) {
|
||||
if (pieces.length != 9) {
|
||||
throw new IllegalArgumentException("The pieces list must be size 9.");
|
||||
}
|
||||
this.pieces = pieces;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks the status of a place on the board. If the location is taken or not.
|
||||
@ -195,10 +211,10 @@ public class Board {
|
||||
if (this.getClass() != o.getClass()) {
|
||||
return false;
|
||||
}
|
||||
Board other = (Board) o;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
if (this.pieces[i].getValue() != other.pieces[i].getValue()
|
||||
|| this.pieces[i].getLoc() != other.pieces[i].getLoc()) {
|
||||
Piece[] other = ((Board) o).getPiecesInOrder();
|
||||
Piece[] ordered = this.getPiecesInOrder();
|
||||
for (int curr = 0; curr < ordered.length; curr++) {
|
||||
if (ordered[curr] != other[curr]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -213,7 +229,11 @@ public class Board {
|
||||
public String toString() {
|
||||
String result = "";
|
||||
for (int i = 0; i < 9; i++) {
|
||||
result += i + " ";
|
||||
if (pieces[i] == null) {
|
||||
result += 0 + " ";
|
||||
} else {
|
||||
result += pieces[i] + " ";
|
||||
}
|
||||
if ((i+1) % 3 == 0) {
|
||||
result += "\n";
|
||||
}
|
||||
|
@ -1,11 +1,16 @@
|
||||
package Assignments.A1.models;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Jonathan Turner
|
||||
* @version Spring 2024
|
||||
*/
|
||||
public class EightPuzzle {
|
||||
|
||||
private List<Board> boards = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -60,6 +60,21 @@ public class Piece {
|
||||
this.setLoc(newLoc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Should only be used when creating the board to set its location.
|
||||
*
|
||||
* @precondition location is valid
|
||||
* @postcondition new location set
|
||||
*
|
||||
* @param newLoc the new location
|
||||
*/
|
||||
public void setLocation(int newLoc) {
|
||||
if (invalidLocation(newLoc)) {
|
||||
throw new IllegalArgumentException("The location should be valid.");
|
||||
}
|
||||
this.loc = newLoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of the piece.
|
||||
*
|
||||
@ -110,6 +125,17 @@ public class Piece {
|
||||
return board.isTaken(desiredLoc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns any string call of the class to just its value.
|
||||
* @precondition none
|
||||
* @postcondition none
|
||||
* @return the value of the piece.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.valueOf(this.value);
|
||||
}
|
||||
|
||||
/* Private Methods Below. End of Java Docs. */
|
||||
|
||||
/* Sets the location for both Moving and Initialization. */
|
||||
|
Loading…
Reference in New Issue
Block a user