CMPS 144 Spring 2022
Prog. Assg. #5: Solving the Slider Puzzle
Due: 11:59pm, April 20

Recall that the Uniform-cost Single-source Shortest Paths Problem —which is to find, for each vertex v in a given directed graph, a shortest path to v from a specified "source" vertex— can be solved using a breadth-first search. Beginning with the source vertex, we "explore" from it to "discover" those vertices that are at distance one from the source. Then we explore from each of those vertices to discover any vertices that are at distance two from the source. Then we explore from the vertices at distance two to discover any vertices that are at distance three, etc., etc. To ensure that vertices are explored from in the same order that they are discovered, a queue of discovered-but-not-yet-explored-from vertices is maintained.

An execution of this algorithm can be envisioned as a level-by-level traversal of a rooted tree. The root node corresponds to the source vertex. Its children correspond to the vertices at distance one, its grandchildren correspond to the vertices at distance two, etc., etc.

A solution to a given slider puzzle problem can be computed in the same way. Here, however, each node in the tree that the algorithm traverses corresponds to a slider puzzle configuration. The root node corresponds to the starting configuration; its children are those configurations that can be reached in a single move; its grandchildren are those configurations that can be reached in two moves, etc., etc. (Configurations that are duplicates of ones appearing higher in the tree, or to the left in the same level of the tree, are omitted.)

An illustration of a successful search for a solution to a given 8-puzzle configuration is shown to the right. The label on each edge indicates the move (Up, Down, Right, or Left) that transforms the parent node's configuration into the child's. (In this example, no Left move ever produces a "new" configuration.) Notice that the search is terminated as soon as the goal configuration is discovered.


Java Classes

The following Java classes are provided, the last of which is in need of completion.

Algorithm to Solve the Slider Puzzle Problem

The algorithm below, expressed in Java-like pseudo-code, finds a shortest sequence of moves that transforms a given Slider Puzzle configuration into the standard goal configuration. Its result is a string composed of the characters 'U', 'D', 'L', and 'R', which stand for the UP, DOWN, LEFT, and RIGHT moves of a puzzle.

The algorithm essentially performs a breadth-first traversal of a tree of puzzle configurations, with the specified starting configuration at the root, until it encounters the specified goal configuration.

/* Assuming that there is a sequence of moves leading from the
** given start configuration to the given goal configuration,
** a String containing a description of a shortest such sequence
** is returned.  (That description encodes each kind of move using 
** the character code defined for it in the SliderPuzzleConfig class.
** Those codes are 'U', 'D', 'L', and 'R'.)
*/
public String solution(SliderPuzzleConfig startConfig,
                       SliderPuzzleConfig goalConfig) {
   treeNode = new solverNode(startConfig, "")
   toBeExplored = new Queue()
   toBeExplored.enqueue(treeNode)
   while (!toBeExplored.isEmpty()) {
      treeNode = toBeExplored.dequeue()
      config = treeNode.configuration
      for direction in ['U', 'D', 'L', 'R'] {
         if (config.canMove(direction)) {
            newConfig = config.clone()
            newConfig.move(direction)
            if (newConfig was not discovered earlier) {
               moveSeq = treeNode.moveSeq + direction
               newTreeNode = new solverNode(newConfig, moveSeq)
               toBeExplored.enqueue(newTreeNode)
               if (newConfig is same as goalConfig) {
                  return newConfig.moveSeq
               }
            } 
         }
      }
   }
   // If execution reaches here, there is no sequence of
   // moves that transforms the start configuration into
   // the goal configuration.
   return null
}


Sample Execution of SPS_Tester

What follows depicts a run of the SPS_Tester program when invoked from a UNIX command line interface. That invocation specifies the Java program to be executed, followed by a list of command-line arguments (or what jGrasp refers to as "run arguments"). The four command-line arguments that SPS_Tester expects to receive provide these values:

  1. number of rows in the puzzle,
  2. number of columns in the puzzle,
  3. a seed value for a pseudo-random number generator, and
  4. the number of pseudo-random moves to be made —starting with the standard goal configuration— to obtain the starting configuration.
$ java SPS_Tester 3 4 27 15
Starting configuration is
 1  2  3  4
 6  7 10  8
 5  9  - 11

Path of length 7 found:

 1  2  3  4
 6  7 10  8
 5  9  - 11

After moving U:
 1  2  3  4
 6  7  -  8
 5  9 10 11

After moving L:
 1  2  3  4
 6  -  7  8
 5  9 10 11

After moving L:
 1  2  3  4
 -  6  7  8
 5  9 10 11

After moving D:
 1  2  3  4
 5  6  7  8
 -  9 10 11

After moving R:
 1  2  3  4
 5  6  7  8
 9  - 10 11

After moving R:
 1  2  3  4
 5  6  7  8
 9 10  - 11

After moving R:
 1  2  3  4
 5  6  7  8
 9 10 11  -

Goodbye