// PuzzleAsArray // adapting code from Kiri Wagstaff /* locating tiles: +-----> | | V */ public class PuzzleAsArray implements IPuzzle { private int BLANK; // representation of blank tile (0) private int SIZE; // size of puzzle private int[][] puzzle; // array of "tiles" private int LEFT, RIGHT; // limits of horz dimensions private int TOP, BOTTOM; // limits of vert dimensions private int blankRow, blankCol; // location of blank tile private int RANDOMNESS; // Randomness of scambling puzzle // Create an Array Puzzle: // Originally, create a tile size SIZE and set params accordingly: public PuzzleAsArray() { setDifficulty("hard"); setPuzzleDims(3); createPuzzle(); } // Set difficulty (how much puzzle is scrambled): private void setDifficulty(String level) { if (level.equals("easy")) RANDOMNESS=(int) (Math.random()*(5)+1); else RANDOMNESS=(int) (Math.random()*(100)+1); } // Set border index values for puzzle: private void setPuzzleDims(int size) { SIZE = size; LEFT=TOP=0; RIGHT=BOTTOM=size-1; } // Create initial puzzle with an array and reset it: private void createPuzzle() { puzzle = new int[SIZE][SIZE]; resetPuzzle(); } // Restore puzzle to initial state: public void resetPuzzle() { // Fill puzzle with ascending numbers starting from 1. // Work from left-to-right, then top-down: int count = 1; for (int row=0; row < SIZE; row++) for (int col=0; col < SIZE; col++) puzzle[row][col]=count++; // Set location of blank tile: blankRow = BOTTOM; blankCol = RIGHT; puzzle[blankRow][blankCol] = BLANK; } // Return true if puzzle is solved: public boolean isSolved() { // Are values inside the array OK? int count = 1; for (int row=0; row < SIZE; row++) for (int col=0; col < SIZE; col++) { if (puzzle[row][col] != count) if (puzzle[row][col]!=BLANK || // not counting blank (0) in count++ puzzle[BOTTOM][RIGHT] != BLANK) // something else is in blank tile starting position! return false; count++; } return true; } // Move a tile in the specified direction (dir: N/S/E/W), if possible. // Return true if the move was successful; otherwise, false: public boolean move(char dir) { switch (dir) { case 'N': if (blankRow == BOTTOM) return false; // no tile to move north // Swap the blank and what's right below it puzzle[blankRow][blankCol] = puzzle[blankRow+1][blankCol]; puzzle[blankRow+1][blankCol] = BLANK; blankRow++; break; case 'S': if (blankRow == TOP) return false; // no tile to move south // Swap the blank and what's right above it puzzle[blankRow][blankCol] = puzzle[blankRow-1][blankCol]; puzzle[blankRow-1][blankCol] = BLANK; blankRow--; break; case 'E': if (blankCol == LEFT) return false; // no tile to move east // Swap the blank and what's to the left of it puzzle[blankRow][blankCol] = puzzle[blankRow][blankCol-1]; puzzle[blankRow][blankCol-1] = BLANK; blankCol--; break; case 'W': if (blankCol == RIGHT) return false; // no tile to move west // Swap the blank and what's to the right of it puzzle[blankRow][blankCol] = puzzle[blankRow][blankCol+1]; puzzle[blankRow][blankCol+1] = BLANK; blankCol++; break; } return true; } // Scrambles the puzzle by making a series of random moves: public void scramble() { resetPuzzle(); for (int r=0; r < RANDOMNESS; r++) { int m = (int)(Math.random()*SIZE); switch (m) { case 0: move('N'); break; case 1: move('S'); break; case 2: move('E'); break; case 3: move('W'); break; } } } // Display puzzle: public void display() { System.out.println(this); } // String representation of tiles: public String toString() { // Create row based on # of largest digits (size^2-1) // Each time print a number, print # of spaces less than max digits // Standard row: +-...+-... final int MAXSIZE = digitCount(SIZE*SIZE - 1); // number of digits in largest tile # String rowBorder = "+"; // start of row border for (int row=0;row