Skip to main content
1 of 8

Logic for shuffling sliding puzzle

i'm working on a sliding puzzle, one little project as a hobbie, 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.

Here's the code:

public int[] moveTile(int clickedRow, int clickedCol, int x, int y) {
  // { ... shuffle logic ... }
  return new int[]{clickedRow + y, clickedCol + x}; //returns new tile position on the grid
}

public void shuffle() {
  currTile = moveTile(currTile[0], currTile[1], 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], 0, 1);
      }
    }else if (currTile[0] == 0 && currTile[1] == tileGrid.length - 1) { // bottom left
      // can move up or right
      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], 0, 1); // 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);
      }
    }
  }
}