I'm working on a sliding puzzle, one little project as a hobby, and yesterday I thought that instead of working on an algorithm to figure out a solved puzzle, it would be easier to make an algorithm that "shuffles" the tiles from a solved position. I came up with this and it works, but I don't know if it's elegant enough or it could be compressed into fewer lines of code because if I had to go back to it I think it could be tiresome.
public int[] moveTile(int clickedRow, int clickedCol, int x, int y) {
// { ... moves the tile ... }
return new int[]{clickedRow + y, clickedCol + x}; //returns new tile position on the grid
}
public void shuffle() {
int[] currTile = {tileGrid.length - 1, 0}; // first move, to the right
for (int i = 0; i < 1000; i++) { // it's set to 1000 for testing
if (currTile[0] == tileGrid.length - 1 && currTile[1] == tileGrid[0].length - 1) { // top right
// can move left or down
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], 0, -1);
} else {
currTile = moveTile(currTile[0], currTile[1], -1, 0);
}
} else if (currTile[0] == 0 && currTile[1] == 0) { // bottom left
// can move up or right
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], 0, 1);
} else {
currTile = moveTile(currTile[0], currTile[1], 1, 0);
}
} else if (currTile[0] == 0 && currTile[1] == tileGrid.length - 1) { // bottom right
// can move up or left
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], -1, 0); // left
} else {
currTile = moveTile(currTile[0], currTile[1], 0, 1); // up
}
} else if (currTile[0] == 0 && currTile[1] > 0 && currTile[1] < tileGrid.length - 1) { // bottom row
//can move up, left or right
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], 0, 1); // up
} else {
currTile = moveTile(currTile[0], currTile[1], ran.nextInt(1 + 1 + 1) - 1, 0); // left or right
}
} else if (currTile[0] == tileGrid.length - 1
&& currTile[1] > 0 && currTile[1] < tileGrid.length - 1) { // top row
//can move down, left or right
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], 0, -1); // down
} else {
currTile = moveTile(currTile[0], currTile[1], ran.nextInt(1 + 1 + 1) - 1, 0); // left or right
}
} else if (currTile[1] == 0
&& currTile[0] > 0 && currTile[0] < tileGrid.length - 1) { // left column
//can up down or right
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], 1, 0); // right
} else {
currTile = moveTile(currTile[0], currTile[1], 0, ran.nextInt(1 + 1 + 1) - 1); // up or down
}
} else if (currTile[1] == tileGrid.length - 1
&& currTile[0] > 0 && currTile[0] < tileGrid.length - 1) { // right column
//can move up or down or left
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], -1, 0); // left
} else {
currTile = moveTile(currTile[0], currTile[1], 0, ran.nextInt(1 + 1 + 1) - 1); // up or down
}
} else if (currTile[0] == tileGrid.length - 1 && currTile[1] == 0) {
//can only move right or down
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], 1, 0);
} else {
currTile = moveTile(currTile[0], currTile[1], 0, -1);
}
} else if (currTile[0] == 0 && currTile[1] == tileGrid.length) {
//can only move top or left
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], 0, 1);
} else {
currTile = moveTile(currTile[0], currTile[1], -1, 0);
}
} else {
// can move in any direction
if (ran.nextBoolean()) {
currTile = moveTile(currTile[0], currTile[1], ran.nextInt(1 + 1 + 1) - 1, 0);
} else {
currTile = moveTile(currTile[0], currTile[1], 0, ran.nextInt(1 + 1 + 1) - 1);
}
}
}
}
As clarification, currTile is the hole, swapping it with random tiles will shuffle the puzzle.
In the first state, currTile (hole) is in the top left of the grid:
int[] currTile = {tileGrid.length - 1, 0};
tileGrid.length
= amount of rows, -1 = top row, as top row = number of rows -1.
0 = col to the left.