前のバージョンを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