Computer Science 2611
Fall 2004
Programming Assignment 3

Date assigned: 9/20/04


A puzzle

The Towers of Hanoi puzzle has three posts and some number n of disks. Each disk has a hole in the middle, so that it can be put on a post, and the disks are of different sizes.

Initially, the disks are all stacked on the leftmost post, with larger disks closer to the bottom and smaller disks closer to the top. For example, if there are three disks, the puzzle starts out looking like this.

The object is move all of the disks from the leftmost post to the rightmost post. So when the puzzle is solved, it looks like this.

But there are some rules that must be followed.

  1. Only one disk can be held in your hand at a time. The other disks must be on posts.

  2. A disk can only be put down by placing it on one of the posts. For example, you can't put a disk on the table beside the puzzle.

  3. No disk can ever be put on top of a smaller disk.


The assignment

Write a program that prints instructions for solving the Towers of Hanoi puzzle. It should read four things from the user: (1) a number n of disks, (2) a source post character (3) a destination post character, and (4) an intermediate post character. Your program should print instructions for moving n disks from the source post to the destination post, using the intermediate post as a place to put disks during the move.

The disks are numbered from the top to the bottom, with disk 1 on top. Each instruction should say which disk is to be moved. It will always be the topmost disk, but give the disk number anyway.

Number the moves, starting at move 1. For example, suppose the number of disks n is 3, the source post is called L, the destination post is called R and the intermediate post is called M. Then the following would be printed.

  1. Move disk 1 from L to R.
  2. Move disk 2 from L to M.
  3. Move disk 1 from R to M.
  4. Move disk 3 from L to R.
  5. Move disk 1 from M to L.
  6. Move disk 2 from M to R.
  7. Move disk 1 from L to R.


Hints and requirements

Use recursion. We wrote a function similar to what you need in class, but yours will need to do a little more. Here is the function that we wrote in class.

//========================================================
// hanoi(start,end,other,n) prints instructions to move
// n disks from post start to post end, using post
// other for storage.
//========================================================

void hanoi(char start, char end, char other, int n)
{
  if(n > 0) 
  {
    hanoi(start, other, end, n-1);
    cout << "Move a disk from " << start << " to " << end << endl;
    hanoi(other, end, start, n-1);
  }
}
However, this version does not number the lines, and does not say which disk is being moved.

Modify the hanoi function so that it takes one more parameter, the instruction number to use for the first line. Also modify it so that it returns the number of moves used. For example, hanoi('L', 'R', 'M', 3, 12) would print instructions starting at line 12.

  12. Move disk 1 from L to R.
  13. Move disk 2 from L to M.
  14. Move disk 1 from R to M.
  15. Move disk 3 from L to R.
  16. Move disk 1 from M to L.
  17. Move disk 2 from M to R.
  18. Move disk 1 from L to R.
where the numbering has started from 12. It would return 7, since a total of 7 moves were made.

Think carefully about the parameters to use in the recursive calls to hanoi, and what to do with the value that hanoi returns.

Requirements

  1. Do not use any global variables in your program. Rely on passing parameters. We have not talked about global variables, but if you know about them, do not use them. A program that uses global variables will be returned ungraded.

  2. For this assignment, do not use reference parameters. Pass all parameters by value.

Turning in your program

Test your solution, and check whether the instructions that it prints work. Do not ask the user which line number to start with. Start with line 1. (Can you see why you generalized hanoi to start with any line number?)

When it is working, print your program and turn it in. Be sure that your program is well written and well commented. Write the contract for your function into your file before you write the function body.


A note on reading characters

If you write

  char c;
  cin >> c;
your program will first skip over all characters that it considered white space characters, and then get a single character. That is what you want to do to read a post name.

You might have seen an alternative way to read a character, as follows.

  char c;
  cin.get(c);
This will read the next character, regardless of what it is. For example, if the next character is a space, then it will store the space character into variable c. If you ask the user to type a character, the user might type character R followed by a return (newline) character. If you now read two characters using get, you will first that the 'R', and then the newline character. That will not be what you want. A newline character is considered to be white space, so the >> operator will ignore it.