In 8-puzzle I want to count the number of moves it would take to move a specific tile to it's goal place. The problem is my method for this is >100 lines long which is obviously way too much. I'll only include part of that method that counts steps to move the piece to the right row if the goal row is higher. It gives the idea, it is probably hard to read even with that piece of it only, I did comment profusely though.
To further illustrate what the code does - for state {{0,2,3},{4,1,6},{7,8,5}} the count of steps for moving the 1 tile to first spot would be 5:
2 3 2 3 2 1 3 2 1 3 1 3 1 3
4 1 6 => 4 1 6 => 4 6 => 4 6 => 2 4 6 => 2 4 6
7 8 5 7 8 5 7 8 5 7 8 5 7 8 5 7 8 5
And for the code ( or bits and pieces of it):
// Finding the nr of steps it would take to move tile to it's goal place
public int countSteps(int tileNr) {
int steps = 0;
int[] goal = findGoal(tileNr);
int[] current = findTile(tileNr);
int[] empty = findTile(0);
GameState copy = new GameState(this);
while (goal[0] != current[0] && goal[1] != current[1]) {
// If the tile needs to be moved upwards (row coord is smaller in
// goal)
if (goal[0] < current[0]) {
if (empty[0] == current[0] - 1 && empty[1] == current[1]) {
// If empty above current tile, switch them
steps++;
current = empty;
empty[0]++;
} // Else have to move the empty tile to above current
else if (empty[1] == current[1]) {
if (empty[0] < current[0] - 1) {
// If empty too high in the right column, move empty
// tile down
steps++;
empty[0]++;
}
if (empty[0] > current[0]) {
// If empty below current, move out from that that
// column
steps++;
if (empty[1] < 2)
empty[1]++;
else
empty[1]--;
}
} else if (empty[0] == current[0]) {
if (empty[1] < current[1]) {
// If empty to the right in right row
// move to the left
steps++;
empty[1]++;
}
if (empty[1] > current[1]) {
// If empty to the left in right row move to the right
// column
steps++;
empty[1]--;
}
}
}
}
return steps;
}
// Finding coords for the tile in goal state
public int[] findGoal(int tileNr) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (goalState[i][j] == tileNr)
return new int[] { i, j };
}
}
return new int[] { -1, -1 };
}
// Finding coords for the tile in current state
public int[] findTile(int tileNr) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
if (state[i][j] == tileNr)
return new int[] { i, j };
}
}
return new int[] { -1, -1 };
}