/* Some Psudo Code
 TowersOfHanoi(k, source, auxiliary, destination)
   {
       If k=1 move disk from source to destination;  
       Else, 
            {  
                   TowersOfHanoi(top k-1, source, destination,auxiliary);
                    Move the kth disk from source to destination;
                   TowersOfHanoi(k-1, auxiliary, source, destination);
           }
}
*/
/** 
 *  TowersOfHanoi.java  (with Minor Modifications)
 *  @original author Lars Vogel
 *   
*/

public class TowersOfHanoi {
    static int theCount=0;

    public static void move(int n, int startPole, int endPole) {
        theCount++;
        if (n== 0) {
            return; 
        }
        char[] thePoles={'A','B','C'};
        int intermediatePole = 6-startPole - endPole;
        move(n-1, startPole, intermediatePole);
        System.out.println("Move " +n + " from " + thePoles[startPole-1] + " to " +thePoles[endPole-1]);
        move(n-1, intermediatePole, endPole);
    }

    public static void main(String[] args) {
        String thePoles="ABC";  
        move(20, thePoles.indexOf('A')+1, thePoles.indexOf('B')+1);
        System.out.println("\n\nTotal Moves - "+theCount);
    }
}



/**
 * TowersOfHanoi.java -(Minor Modifications) 
 *   @original_author Grant William Braught
 *    Dickinson College 
 */
import java.io.*;
public class TowersOfHanoi {
    public static void main (String[] args) {

        char fromPeg, toPeg, auxPeg;
        int numDisks; 
        printIntro();                        // Display an introductory screen.
        fromPeg = getFromPeg();              // Get from the user
        toPeg =   getToPeg(fromPeg);         // Get from the user
        auxPeg =  findAuxPeg(fromPeg, toPeg);//  determine
        numDisks =getNumDisks();             // Get from the user
        System.out.println();
        System.out.println("Move\tFrom\tTo");
        System.out.println("Disk\tPeg\tPeg");
        System.out.println("--------------------");
        towers(fromPeg,toPeg,auxPeg,numDisks);
    }

    static void towers(char fromPeg, char toPeg, char auxPeg,
                       int numDisks) {

        // Base Case:  If there is only one disk just move it and we're done!
        if (numDisks == 1) {
            System.out.println(numDisks + "\t" +
                               fromPeg + "\t" + 
                               toPeg);         
        }
        // Recursive Case:   This takes three steps...
        else {

            // Step 1: Move numDisks-1 disks from the fromPeg to the auxPeg using the toPeg.
            towers(fromPeg, auxPeg, toPeg, numDisks-1);
            // Step 2: Move 1 disk from the fromPeg to  the toPeg.
            System.out.println(numDisks + "\t" +  fromPeg + "\t" + toPeg);  
            // Step 3: Move the numDisks-1 disks from the auxPeg to the toPeg using the fromPeg.
            towers(auxPeg, toPeg, fromPeg, numDisks-1);
        }
    }
    /**
     * Read the name of the peg that is to
     * contain the disks at the start of the game.
     */
    static char getFromPeg() {
        char thePeg = 'z';
        // Prompt the user for a peg until they enter a valid peg
        while (thePeg != 'a' && thePeg != 'A' &&
               thePeg != 'b' && thePeg != 'B' &&
               thePeg != 'c' && thePeg != 'C') {
            System.out.print("Enter the peg that holds the disks " +
                             "[A, B, C]: ");
            try {
                thePeg = getLetter();
            } catch (Exception ex) {
            };
        }
        return thePeg;
    }

    /**
     * Read the name of the peg that the disks
     * should end up on at the end of the game.
     */
    static char getToPeg(char fromPeg) {
        char thePeg = 'z';
        while (thePeg != 'a' && thePeg != 'A' &&
               thePeg != 'b' && thePeg != 'B' &&
               thePeg != 'c' && thePeg != 'C' ||
               thePeg == fromPeg) {
            System.out.print("Enter the peg to move the disks to " +
                             "[A, B, C]: ");

            try {
                thePeg = getLetter();
            } catch (Exception ex) {
            };
        }
        return thePeg;
    }

    static char findAuxPeg(char fromPeg, char toPeg) {
        char auxPeg;
        // Is peg A being used?
        if (fromPeg == 'a' || fromPeg == 'A' ||
            toPeg == 'a' || toPeg == 'A') {
            // Is peg B being used?
            if (fromPeg == 'b' || fromPeg == 'B' ||
                toPeg == 'b' || toPeg == 'B') {
                auxPeg = 'C';
            } else {
                // The pegs A and C are used so
                auxPeg = 'B';
            }
        } else {
            // peg A is not used so
            auxPeg = 'A';
        }
        return auxPeg;
    }

    static int getNumDisks() {
        int numDisks = -1;
        while (numDisks <= 0) {
            System.out.print("Enter the number of disks [ > 0]: ");
            try {
                numDisks = getNumber();
            } catch (Exception ex) {
            };
        }
        return numDisks;
    }

    /**
     * Print an introductory screen
     */
    static void printIntro() {
        System.out.println("Towers of Hanoi!\n\n");
        System.out.println("     |      |      |");
        System.out.println("1    +      |      |");
        System.out.println("2   -+-     |      |");
        System.out.println("3  --+--    |      |");
        System.out.println("4 ---+---   |      |");
        System.out.println("=======================");
        System.out.println("     A      B      C\n");
    }

    static int getNumber() throws java.io.IOException {
        String theNumber;
        int number = 0;
        BufferedReader in = new BufferedReader (new InputStreamReader(System.in));
        theNumber = in.readLine();
        number = Integer.parseInt(theNumber);
        return number;
    }
    static char getLetter()  throws java.io.IOException {
        String theLetter;
        BufferedReader in = new BufferedReader (new InputStreamReader(System.in));
        theLetter = in.readLine();
        return theLetter.charAt(0);
    }
}