2002年3月19日更新(新規アップロード)
  関谷トップページへ   このアプレットの実行

hanoi.java ハノイの塔アプレット

//********************************************************************
// hanoi.java
//********************************************************************
// Lalaniほか,スリーエーシステムズ訳,JAVAプログラミングケーススタディ、翔永社,1997.2,pp.435-458
// GUI,マルチスレッド、キー割り込みなどを改造   1997.3.14 z.sekiya
//

import java.applet.*;
import java.awt.*;

//********************************************************************

public class hanoi extends Applet implements Runnable
  {
    Graphics g;

    static public Image background;
    static public int width;
    static public int height;
    static public int delay = 500;
    static public int seq ;

    private boolean done_loading_image = false;
    private int total_disks = 5;
    private Thread my_thread;
    private boolean thread_started = false;
    private boolean flag = false; // 1997.3.14 z.sekiya
    private int pm0=0;
    private String keypm0="0";

    tower t[];

    int from_tower = 0;
    int to_tower   = 2;

    //--------------------------------

    public void init()
      {
        g = getGraphics();

        String parameter;

        parameter = getParameter("TOTAL");
        if (parameter != null)
          total_disks = Integer.parseInt(parameter);

        parameter = getParameter("DELAY");
        if (parameter != null)
          delay = Integer.parseInt(parameter);

        width  = size().width;
        height = size().height;

        background = getImage(getCodeBase(), "egypt.gif");

        Image offScrImage = createImage(width, height);
        Graphics offScrGC = offScrImage.getGraphics();
        offScrGC.drawImage(background, 0, 0, this);

        t = new tower[3];

        t[0] = new tower(g);
        t[1] = new tower(g);
        t[2] = new tower(g);

        for (int i = 0; i < total_disks; i++)
          t[0].add(i);   
      }

    //--------------------------------

    public boolean imageUpdate(Image img, int infoflags, int x, int y,
                               int width, int height)
      {
        if (infoflags == ALLBITS)
          {
            done_loading_image = true;
            repaint();
            return false;
          }
        else
          return true;
      }

    //--------------------------------

    public void paint(Graphics g)
      {
        if (!done_loading_image)
          showStatus("Tower of Hanoi:  loading image");

        else
          {
            if (thread_started)
              if (my_thread.isAlive())
                showStatus("Tower of Hanoi:  Running(Click to suspend or resume.Next disk:'+','0','-')");
              else
                showStatus("Tower of Hanoi:  Click again to restart(Next disk:'+','0','-')");
            else
              showStatus("Tower of Hanoi:  Click to start(Next disk:'+','0','-')");

            width  = size().width;
            height = size().height;

            g.drawImage(background, 0, 0, width, height, this);

            int x_inc = width / 10;

            t[0].paint(x_inc*1, x_inc*2, height);
            t[1].paint(x_inc*4, x_inc*2, height);
            t[2].paint(x_inc*7, x_inc*2, height);
          }
      }

    //--------------------------------

    public boolean mouseDown(Event evt, int x, int y)
    {
        double xd; int i;
        if (!thread_started || !my_thread.isAlive())
          {
            my_thread = new Thread(this);
            my_thread.start();
            showStatus("Tower of Hanoi:  Running(Click to suspend  or resume.)");
            thread_started = true;
          }
       else {
        if(flag)
            my_thread.suspend();
        else
            my_thread.resume();
        flag = !flag;
        xd=1.00000;
        for(i=1; i<100000; i++)
            xd *= 1.0000000001;
      }
      return true;
    }

    //--------------------------------

    public void run()
      {
        seq =0;

        move_tower(total_disks, from_tower, to_tower, 1);

        int disk_old =total_disks;
        int seqmax =seq;
        int temp = to_tower;
        to_tower = from_tower;
        from_tower = temp;

        if(pm0==1)
          t[from_tower].add(total_disks);
        else if(pm0==-1)
          t[from_tower].remove(total_disks-1);
        total_disks+= pm0 ; if(total_disks<1) total_disks = 1;
        delay -= pm0*20; if(delay<10) delay=10;

/*        repaint();  */
            g.setColor(Color.white);
            g.fillRect(62,2,110,37);
            g.setColor(Color.black);
            g.drawString("Key:"+ keypm0,65,15);
        g.drawString("oldDisk:"+String.valueOf(disk_old),105,15);
        g.drawString("maxSeq:"+String.valueOf(seqmax),105,33);

        g.setColor(Color.white);
        g.fillRect(2,2,60,37);
        g.setColor(Color.black);
        g.drawString("Disk:"+String.valueOf(total_disks),10,15);

        showStatus("Tower of Hanoi:  Click again to restart(Next disk:'+','0','-')");
      }

    //--------------------------------

    private void move_tower(int disks, int from, int to, int using)
      {
        if (disks > 0)
          {
            move_tower(disks-1, from, using, to);

            seq++;
            g.setColor(Color.white);
            g.fillRect(2,17,60,20);
            g.setColor(Color.black);
            g.drawString("Seq:"+String.valueOf(seq),10,33);

            g.setColor(Color.white);
            g.fillRect(62,2,40,20);
            g.setColor(Color.black);
            g.drawString("Key:"+ keypm0,65,15);

            move_disk(from, to);

            move_tower(disks-1, using, to, from);
          }
      }

    //--------------------------------

    private void move_disk(int from, int to)
      {
        int disk = t[from].pop();
        t[to].push(disk, from);
      }

    //--------------------------------
    public boolean keyDown(Event e, int key){

      switch (key) {
        case 43: pm0= 1; keypm0="+";  break; //  +
        case 45: pm0=-1; keypm0="-";  break; //  -
        case 48: pm0= 0; keypm0="0";  break; //  0
      }
            g.setColor(Color.white);
            g.fillRect(62,2,30,20);
            g.setColor(Color.black);
            g.drawString("Key:"+ keypm0,65,15);
      return true;
    }
  }