Advertisement
brilliant_moves

TowersOfHanoi.java

Sep 21st, 2012
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5 7.17 KB | None | 0 0
  1. import java.awt.*;
  2. import java.awt.event.*;
  3. import javax.swing.*;
  4.  
  5. public class TowersOfHanoi {
  6.  
  7.     /**
  8.     *   Program:    TowersOfHanoi.java by  Chris Clarke
  9.     *   Created:    22.01.2007
  10.     *   Purpose:    Working graphic model of the well-known
  11.     *           "Towers of Hanoi" challenge: move all disks one by one
  12.     *           from one peg to another, ensuring that each disk is always
  13.     *           placed on top of one that is larger than itself.
  14.     *           Method "goRight" added 18.12.2009.
  15.     *   Modified:   21.09.2012 (JFrame)
  16.     */
  17.  
  18.     public static void main(String[] args) {
  19.         TowersOfHanoiJFrame frame = new TowersOfHanoiJFrame();
  20.         frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
  21.         // Set to a reasonable size.
  22.         frame.setSize(700, 400);
  23.         frame.setVisible(true);
  24.     }
  25. }
  26.  
  27. class TowersOfHanoiJFrame extends JFrame implements ActionListener {
  28.     public TowersOfHanoiJFrame() {
  29.         Container contentPane = getContentPane();
  30.         userControlPanel = new JPanel();
  31.         chSpeed = new Choice();
  32.         chSpeed.add("Slow");
  33.         chSpeed.add("Fast");
  34.         chSpeed.add("Lightning");
  35.         chSpeed.select(1);  // fast
  36.         userControlPanel.add(chSpeed);
  37.         btn = new JButton[max];
  38.         for (int i=0; i<max; i++) {
  39.             btn[i]=new JButton(""+(i+1));
  40.             btn[i].addActionListener(this);
  41.             userControlPanel.add(btn[i]);
  42.         }
  43.         contentPane.add(userControlPanel, BorderLayout.SOUTH);
  44.         setTitle("Towers of Hanoi by Chris Clarke");
  45.     }
  46.  
  47.     public void update(Graphics g) {
  48.         paint(g);
  49.     }
  50.  
  51.     public void paint(Graphics g) {
  52.         String str;
  53.         if (!stacksInitialised) initStax(); // set disks to start position
  54.         redraw(g);
  55.  
  56.         if (play) {
  57.             str=calcAlgorithm(n);   // calculate the algorithm as a String
  58.             // disks are to end up on right-hand peg
  59.             // only applies to odd number of disks
  60.             if (pegRight&&n%2==1)
  61.                 str=goRight(str);
  62.             for (int i=0; (i+2)<=str.length(); i+=2) {
  63.                 String s1 = str.substring(i, i+1);   // 1st char of 2
  64.                 String s2 = str.substring(i+1, i+2); // 2nd char of 2
  65.                 // convert Strings to ints
  66.                 int stFrom=Integer.parseInt(s1);
  67.                 int stTo=Integer.parseInt(s2);
  68.                 // move disk, in array hanoi, from stack stFrom to stTo
  69.                 doPush(stTo, doPop(stFrom));
  70.                 try {
  71.                     if (chSpeed.getSelectedIndex()==0)
  72.                             Thread.sleep(1000); // pause for 1 second
  73.                     else if (chSpeed.getSelectedIndex()==1)
  74.                             Thread.sleep(333); // pause for 1/3 second
  75.                     else if (chSpeed.getSelectedIndex()==2)
  76.                             Thread.sleep(50); // pause for 1/20 second
  77.                 } catch (InterruptedException e) {}
  78.                 redraw(g);
  79.             }
  80.             play=false;
  81.         }
  82.     }
  83.  
  84.     public String goRight(String s) {
  85.         // convert string to ensure disks always end up on the right-hand disk
  86.         String result="";
  87.         for (int i=0; i<s.length(); i++) {
  88.             String temp=s.substring(i, i+1);
  89.             // peg 2 becomes peg 1 and vice versa; peg 0 remains unchanged
  90.             if (temp.equals("1"))
  91.                 result+="2";
  92.             else if (temp.equals("2"))
  93.                 result+="1";
  94.             else result+=temp;
  95.         }
  96.         return result;
  97.     }
  98.  
  99.     public void redraw(Graphics g) {
  100.         deleteDiscs(g);
  101.         drawColumns(g);
  102.         drawDiscs(g);
  103.     }
  104.  
  105.     public void initStax() {       
  106.         hanoi = new int[3][max];
  107.         for (int i=0; i<=2; i++)
  108.             for (int j=0; j<max; j++)
  109.                 hanoi[i][j]=0;
  110.        
  111.         for (int i=0; i<n; i++)
  112.             hanoi[0][i]=i+1;    // hanoi[0][0]=1 is top of stack
  113.  
  114.         disksOnStack = new int[3];
  115.         disksOnStack[0]=n;      // n is the number of disks user chose
  116.         disksOnStack[1]=0;
  117.         disksOnStack[2]=0;
  118.         stacksInitialised=true;
  119.     }
  120.  
  121.     public void doPush(int stk, int currDisk) { // onto top of stack
  122.         for (int i=n-1; i>0; i--)
  123.             hanoi[stk][i]=hanoi[stk][i-1];  // shuffle the rest down
  124.         hanoi[stk][0]=currDisk; // top of stack
  125.         disksOnStack[stk]++;
  126.     }
  127.  
  128.     public int doPop(int stk) {         // from top of stack
  129.         int currDisk=hanoi[stk][0]; // top of stack
  130.         for (int i=0; i<n-1; i++)
  131.             hanoi[stk][i]=hanoi[stk][i+1];  // shuffle the rest up
  132.         disksOnStack[stk]--;
  133.         return currDisk;
  134.     }
  135.  
  136.     public String calcAlgorithm(int i) { // uses recursion to calculate algorithm
  137.         // when n=1, Hanoi(n)="01"
  138.         if (i==1)
  139.             return "01";    // "Remove disk from column 0,
  140.                     // and place it on column 1."
  141.         else {
  142.             /** When n>1, the algorithm (formula) for n disks, is:-
  143.              *  Hanoi(n) = Hanoi(n-1)+("02"or"01")+rm(Hanoi(n-1)),
  144.              *  where:
  145.              *    Hanoi(n-1) is the algorithm for n-1 disks;
  146.              *    the "02" or "01" depends on whether n is even or odd;
  147.              *    and rm is a function applied to Hanoi(n-1)
  148.              */
  149.             String formula = calcAlgorithm(i-1); // eg when #ofdisks=2 "01"
  150.             String rm = reversedAndMirrored(formula, i); // eg     "12"
  151.             if (i%2==0)
  152.                 formula += "02"; // with 2 disks: "01"+"02"="0102"
  153.             else
  154.                 formula += "01";
  155.             formula += rm;  // eg (when # of disks=2) "0102"+"12"="010212"
  156.             return formula;
  157.         }
  158.     }
  159.  
  160.     public String reversedAndMirrored(String s, int n) {
  161.         String s2 = "";
  162.         // reversed sequence
  163.         for (int i=s.length(); i>0; i--) {
  164.             char ch = s.charAt(i-1);    // "01" backwards becomes "10"
  165.             // mirrored left/right
  166.             if (n%2==0) {   // even number of disks
  167.                 if (ch=='0') s2 += "2"; // swap left and right columns
  168.                 else if (ch=='2') s2 += "0"; // for even numbered n
  169.                 else s2 += ch;
  170.             } else {
  171.                 if (ch=='0') s2 += "1"; // swap left and middle columns
  172.                 else if (ch=='1') s2 += "0"; // for odd numbered n
  173.                 else s2 += ch;
  174.             }
  175.         }      
  176.         return s2;
  177.     }  
  178.  
  179.     public void drawColumns(Graphics g) { // draw 'em
  180.         g.setColor(Color.LIGHT_GRAY);
  181.         g.fillRect(85, maxY-100, 555, 50);  // draw base
  182.         for (int i=0; i<=2; i++) {
  183.             g.fillRect(stackX[i], maxY-300, 30, 200); // stackX[0]=150
  184.  
  185. //          g.setColor(Color.white); // number them 0 to 2 on screen
  186. //          g.drawString(" " + (i), stackX[i], maxY-75);
  187. //          g.setColor(Color.LIGHT_GRAY);
  188.         }
  189.     }
  190.  
  191.     public void deleteDiscs(Graphics g) { // wipe the disks out
  192.         g.setColor(Color.white);
  193.         g.fillRect(85, 0, 555, 300);
  194.     }
  195.  
  196.     public void drawDiscs(Graphics g) { // display contents of the array hanoi
  197.         for (int i=0; i<=2; i++) {
  198.             int d=disksOnStack[i];
  199.             for (int j=d-1; j>=0; j--) {
  200.                 int currentDisk = hanoi[i][(d-j)-1];
  201.                 int y=(maxY-100)-((j+1)*sizeY);
  202.                 g.setColor(Color.black);
  203.                 g.drawRect(stackX[i]+14 - (sizeX[currentDisk-1]/2), y-1,
  204.                   sizeX[currentDisk-1]+1, sizeY);
  205.                 g.setColor(Color.red);
  206.                 g.fillRect(stackX[i]+15 - (sizeX[currentDisk-1]/2), y,
  207.                   sizeX[currentDisk-1], sizeY);
  208.             }
  209.         }
  210.     }
  211.  
  212.     public void actionPerformed(ActionEvent e) { // user clicked a button
  213.         for (int i=0; i<max; i++)
  214.             if (e.getSource() == btn[i])
  215.                 n = i+1;
  216.         play=true;
  217.         stacksInitialised=false;
  218.         repaint();
  219.     }
  220.  
  221.     private JPanel userControlPanel;
  222.     private JButton[] btn;
  223.     Choice  chSpeed;        // slow, fast or lightning speed
  224.     int max=10;         // The maximum number of disks.
  225.     int n=1;            // The number of disks as chosen by you.
  226.     int[][] hanoi;          // 3 by max array representing the stacks.
  227.     int[] disksOnStack;     // max disks on stack 0, 0 on stack 1, 0 on stack 2
  228.     int[] stackX= { 150, 350, 550 };    // x-coordinates of stacks
  229.     int sizeY=20;           // Height of each disk.
  230.     int[] sizeX = { 50, 60, 70, 80, 90, 100, 110, 120, 130, 140 };
  231.     boolean play=false;
  232.     boolean stacksInitialised=false;
  233.     static boolean pegRight=true;   // if true, always move disks to right-hand peg
  234.     int maxX = 700, maxY = 400; // The size of the window.
  235. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement