前のバージョンをBouとして残すためクラス名をTouに変更します。
import java.util.*;
import java.awt.*;
import javax.swing.*;
import java.awt.geom.*;
import java.awt.image.*; //BufferedImageを使うため
public class Tou extends JPanel{
static int dmax;
char name;
LinkedList<Integer> pile = new LinkedList<Integer>();
BufferedImage buffimg = new BufferedImage(
200,200,BufferedImage.TYPE_INT_RGB);
Graphics2D bfg = buffimg.createGraphics();
public Tou(char nam,int maisuu) {
name = nam;
while ( maisuu >0 ){
pile.add(maisuu);
maisuu--;
}
drawPile(); //コンストラクトと同時に絵も作ります。
}
public Tou(char nam) {
name = nam;
pile.clear();
drawPile(); //コンストラクトと同時に絵も作ります。
}
public String toString(){ //このメソッドはつかっていません
String x = name + ":";
for ( int p : pile ){
x= x + p + " ";
}
return x;
}
public int rmDisk(){
int diskn = pile.removeLast();
AnimeRemove(diskn); //1枚取り去るアニメを呼ぶ
System.out.println("exec rmDisk "+ diskn);
drawPile(); //改めて絵を作る。
return diskn;
}
public void addDisk(int diskn){
AnimeAdd(diskn); //1枚加えるアニメを呼ぶ
pile.add(diskn);
System.out.println("exec addDisk "+ diskn);
drawPile(); //改めて絵を作る。
}
public int getMaisuu(){
return pile.size(); //枚数を返すメソッド。
}
public Dimension getPreferredSize() {
return new Dimension(200,200);
}
public void paintComponent(Graphics myg){
super.paintComponent(myg);
Graphics2D myg2 = (Graphics2D)myg;
myg2.drawImage(buffimg,0,0,getSize().width,getSize().height,this);
/* BufferedImageから絵をコピーするだけにする。 */
}
public void drawPile(){ //前にpaintComponentにあった絵を作る部分
Color bg =new Color(0xee, 0xee, 0xee);
bfg.setColor(bg);
bfg.fillRect(0, 0, buffimg.getWidth(), buffimg.getHeight());
double boux =buffimg.getWidth()/2;
double minrad =boux*0.1;
double dr =boux*0.8/(dmax-1);
double bottom =buffimg.getHeight()*0.9;
double dh =buffimg.getHeight()*0.8/dmax;
Rectangle2D.Double rec = new Rectangle2D.Double();
int mai = 0;
for ( int diskn : pile ){
mai++;
int g =(int)(127+128/dmax*diskn);
int b =(int)(255-255/dmax*(diskn-1));
bfg.setColor(new Color(0,g,b));
double radius = minrad+dr*(diskn-1);
double x = boux-radius;
double y = bottom-dh*mai;
rec.setRect(x,y,radius*2,dh);
bfg.fill(rec);
bfg.setColor(Color.black);
bfg.draw(rec);
}
repaint(); //paintComponenに描画を指示
}
public void AnimeRemove(int diskn){ //1枚取り去るアニメ
Color bg =new Color(0xee, 0xee, 0xee);
int mai = getMaisuu()+1; //取り去った後に呼ばれている
double boux =buffimg.getWidth()/2;
double minrad =boux*0.1;
double dr =boux*0.8/(dmax-1);
double bottom =buffimg.getHeight()*0.9;
double dh =buffimg.getHeight()*0.8/dmax;
double radius = minrad+dr*(diskn-1);
double x = boux-radius;
double y = bottom-dh*mai;
int g =(int)(127+128/dmax*diskn);
int b =(int)(255-255/dmax*(diskn-1));
Color diskcolor = new Color(0,g,b));
Rectangle2D.Double rec =
new Rectangle2D.Double(x,y,radius*2,dh-1 );
bfg.setColor(bg);
bfg.fill(rec);
bfg.draw(rec);
double movdh=(bottom-dh*(mai))/8;
int movn=0;
while(y+dh>0){
movn++;
y = bottom-dh*mai -movdh*movn;
rec.setRect(x,y,radius*2,dh);
bfg.setColor(diskcolor);
bfg.fill(rec);
repaint();
try {Thread.sleep(100);}
catch(InterruptedException ex) {System.err.println(ex);}
bfg.setColor(bg);
bfg.fill(rec);
bfg.draw(rec);
}
}
public void AnimeAdd(int diskn){ //1枚加えるアニメ
Color bg =new Color(0xee, 0xee, 0xee);
int mai = getMaisuu()+1;
double boux =buffimg.getWidth()/2;
double minrad =boux*0.1;
double dr =boux*0.8/(dmax-1);
double bottom =buffimg.getHeight()*0.9;
double dh =buffimg.getHeight()*0.8/dmax;
double radius = minrad+dr*(diskn-1);
double x = boux-radius;
double y = 0;
Rectangle2D.Double rec
= new Rectangle2D.Double(x,y,radius*2,dh);
int ct = 0;
double movdh=(bottom-dh*(mai))/8;
int g =(int)(127+128/dmax*diskn);
int b =(int)(255-255/dmax*(diskn-1));
Color diskcolor = new Color(0,g,b);
while(bottom-dh*(mai)>y){
bfg.setColor(diskcolor);
bfg.fill(rec);
bfg.setColor(Color.black);
bfg.draw(rec);
//paintImmediately((int)x,(int)y,(int)(radius*2),(int)dh);
repaint();
try {Thread.sleep(100);}
catch(InterruptedException ex) {System.err.println(ex);}
bfg.setColor(bg);
bfg.fill(rec);
bfg.draw(rec);
ct++;
y = movdh*ct;
rec.setRect(x,y,radius*2,dh);
}
}
}

HanoiTou.java。
import java.awt.*;
import javax.swing.*;
public class HanoiTou {
long ct = 0;
public void idou(int n,Tou src,Tou dst,Tou tmp){
if (n > 0){
idou(n-1,src,tmp,dst);
int disk=src.rmDisk();
dst.addDisk(disk);
try {
Thread.sleep(500);
}
catch(InterruptedException ex) {
System.err.println(ex);
}
ct++;
idou(n-1,tmp,dst,src);
}
}
public HanoiTou(int maisuu){
Tou.dmax=maisuu;
Tou tou1 = new Tou('A',maisuu);
Tou tou2 = new Tou('B');
Tou tou3 = new Tou('C');
JFrame dai = new JFrame("Hanoi");
dai.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
dai.setLayout(new GridLayout(1,3,0,0));
dai.add(tou1);
dai.add(tou2);
dai.add(tou3);
dai.pack();
dai.setVisible(true);
try { Thread.sleep(500); }
catch(InterruptedException ex) { System.err.println(ex); }
idou(maisuu,tou1,tou3,tou2);
}
public static void main( String[] args ) {
int n = Integer.parseInt(args[0]);
HanoiTou hanoi = new HanoiTou(n);
System.out.println(hanoi.ct + "回");
}
}
課題
32枚の場合
$ java Hanoi8 32



