ハノイの塔8 (ピラミッドが高層ビルに)

Bou.java の拡張

実行結果はこうなります

100枚の場合

$ java Hanoi8 100

これは整数に切り捨てする場所が間違っているからです。

fillRect()は引数に整数を要求しますから、最後は切り捨てなり四捨五入なり整数化が必要ですが、ここでは計算途中で整数化してしまっています。

特にdr。これは円板の半径の差ですが、枚数が多くなると1より小さくなります。これを切り捨てると0になってしまいます。すると全部の円板が同じ半径になってしまうのです。

変数説明図

Bou.java の一部

   public void paintComponent(Graphics myg){
      super.paintComponent(myg);
      int boux   =(int)getWidth()/2;
      int minrad =(int)(boux*0.1);
      int dr     =(int)(boux*0.8/(dmax-1)); //ここで0になったら
      int bottom =(int)(getHeight()*0.9);
      int dh     =(int)(getHeight()*0.8/dmax);
      int mai = 0;
      for ( int diskn : pile ){
         mai++;
         int g =(int)(127+128/dmax*diskn);
         int b =(int)(255-255/dmax*(diskn-1));
         myg.setColor(new Color(0,g,b));
         int radius = minrad+dr*(diskn-1); //何をかけても0
         int x = boux-radius;
         int y = bottom-dh*mai;
         myg.fillRect(x,y,radius*2,dh); //半径は皆同じに
         myg.setColor(new Color(0,0,0));
         myg.drawRect(x,y,radius*2,dh);
      }
   }

この点は、途中doubleで計算し、最後に切り捨てすることで解消できます。次の改良されたpaintComponent()では半径以外も最後に切り捨てしています。

改良版 Bou.java の一部

   public void paintComponent(Graphics myg){
      super.paintComponent(myg);
      double boux   =getWidth()/2;
      double minrad =boux*0.1;
      double dr     =boux*0.8/(dmax-1); //doubleで計算しておく。
      double bottom =getHeight()*0.9;
      double dh     =getHeight()*0.8/dmax;
      int mai = 0;
      for ( int diskn : pile ){
         mai++;
         int g =(int)(127+128/dmax*diskn);
         int b =(int)(255-255/dmax*(diskn-1));
         myg.setColor(new Color(0,g,b));
         double radius = minrad+dr*(diskn-1); //ここもdoubleで。
         int x = (int)(boux-radius);
         int y = (int)(bottom-dh*mai);
         myg.fillRect(x,y,(int)(radius*2),(int)dh); //最後に切り捨て。
         myg.setColor(new Color(0,0,0));
         myg.drawRect(x,y,(int)(radius*2),(int)dh);
      }
   }

この改良で、次の様になります。

色が黒くなるのはdhが小さいため、drawRectで描かれる枠でfillRectの塗りつぶしが隠れてしまうためでしょう。

もくじ

聖愛中学高等学校
http://www.seiai.ed.jp/
Last Modified