import java.awt.*;
import java.awt.event.*;
public class hanota extends Frame implements ActionListener,TextListener,ItemListener //定义新的窗口类
{ static int n=1; //初始化盘子的个数
static int timect=19; //演示的时间设置为中等
static int ah=550; //原柱,中间柱,目的柱的高度
static int bh=550;
static int ch=550;
static hanota frm=new hanota(); //创建窗口对象
static Label lab1=new Label("请输入盘子个数(1~10)");
static TextField txt1=new TextField(2); //创建取得用户定义的盘子个数的文本区
static Label lab2=new Label("演示速度");
static Checkbox ckb1=new Checkbox("快"); //用户对演示的时间设置所使用的单选框
static Checkbox ckb2=new Checkbox("中");
static Checkbox ckb3=new Checkbox("慢");
static Button btn1=new Button("演示"); //创建按钮
static Button btn2=new Button("退出");
static Button btn3=new Button("刷新");
static Label lab[]=new Label[10]; //使用标签对象做盘子,最多10个盘
public static void main(String args[])
{ CheckboxGroup grp=new CheckboxGroup(); //创建单选框组
btn1.addActionListener(frm); //设置按钮的事件监听者为FRM
btn2.addActionListener(frm);
btn3.addActionListener(frm);
txt1.addTextListener(frm); //设置文本的事件监听者为FRM
ckb1.setCheckboxGroup(grp); //设置单选框的组grp
ckb2.setCheckboxGroup(grp);
ckb3.setCheckboxGroup(grp);
ckb1.addItemListener(frm); //设置单选框的事件监听者为FRM
ckb2.addItemListener(frm);
ckb3.addItemListener(frm);
frm.setResizable(false); //设置窗口不可改变大小
frm.setLayout(null);
frm.setTitle("汉诺塔问题的直观演示");
frm.setSize(800,600);
frm.setBackground(Color.pink);
lab1.setBounds(20,560,150,15); //初始所有标签,按钮,文本框,单选框的位置
txt1.setBounds(170,560,20,15);
lab2.setBounds(20,580,60,15);
ckb1.setBounds(90,580,30,15);
ckb2.setBounds(120,580,30,15);
ckb3.setBounds(150,580,30,15);
btn1.setBounds(340,560,120,30);
btn2.setBounds(600,560,120,30);
btn3.setBounds(340,560,120,30);
frm.add(txt1); //加载标签,按钮,文本框,单选框到窗口
frm.add(lab1);
frm.add(lab2);
frm.add(btn1);
frm.add(btn2);
frm.add(btn3);
frm.add(ckb1);
frm.add(ckb2);
frm.add(ckb3);
frm.setVisible(true); //设置各组件对象是否可见
btn1.setVisible(false);
btn3.setVisible(false);
frm.addWindowListener(new WindowAdapter() //设置窗口关闭按钮是可用
{public void windowClosing(WindowEvent e)
{System.exit(0);
}
});
}
public void paint(Graphics g) //绘制各个塔柱的位置
{ g.drawLine(20,550,260,550);
g.drawLine(140,50,140,550);
g.drawLine(280,550,520,550);
g.drawLine(400,50,400,550);
g.drawLine(540,550,780,550);
g.drawLine(660,50,660,550);
}
public void actionPerformed(ActionEvent e) //设置按钮事件
{ Button btn=(Button) e.getSource();
if(btn==btn1) //btn1为演示开始按钮
{
for(int i=0;i<=n-1;i++) //建立盘子对象并加载到窗口
{ lab[i]=new Label();
lab[i].setSize(24*(i+1),50);
lab[i].setLocation(140-lab[i].getWidth()/2,550-lab[i].getHeight()*(n-i));
lab[i].setBackground(Color.red);
frm.add(lab[i]);
}
btn1.setVisible(false);
for(double i=1;i<=Math.pow(10,6);i++);
frm.hanoi(lab,n,140,400,660); //汉诺塔演示的核心程序的调用
btn3.setVisible(true); //演示结束显示刷新按钮
txt1.setVisible(false);
}
if(btn==btn3) //刷新,回到初始状态
{ btn3.setVisible(false);
btn1.setVisible(true);
for(int i=0;i<=n-1;i++)
frm.remove(lab[i]);
txt1.setVisible(true);
ah=550-50*n;
bh=550;
ch=550;
}
if(btn==btn2) //退出
System.exit(0);
}
public void textValueChanged(TextEvent e) //的到用户指定的盘子的个数
{ TextField txt=(TextField) e.getSource();
if(txt==txt1)
{ try{n=Integer.parseInt(txt1.getText());} //对输入的异常处理
catch(NumberFormatException f){btn1.setVisible(false);
return;}
if(n>0&&n<=10) //对输入的异常处理
{ ah=550-50*n;
btn1.setVisible(true);
}else
btn1.setVisible(false);
}
}
public void itemStateChanged(ItemEvent e) //用户设置演示中盘子移动快慢
{if(ckb1.getState()==true)
timect=18;
if(ckb2.getState()==true)
timect=19;
if(ckb3.getState()==true)
timect=20;
}
public void settimectr(int timectc) //移动的间隔时间
{for(double h=1;h<=Math.pow(2,(double)timectc);h++);{
Graphics m;
m = this.getGraphics();
m.setColor(Color.BLACK);
paint(m);
}
}
public void setactcolor(Label labl[],int ncl) //盘子移动时的颜色,绿色
{labl[ncl-1].setBackground(Color.green);
}
public void setcolorbak(Label labl[],int ncl) //盘子静止时的颜色,红色
{labl[ncl-1].setBackground(Color.black);
}
public void hanoi(Label labc[],int nc,int xc,int yc,int zc) //递归实现
{ if(nc==1)
{setactcolor(labc,1);
settimectr(timect);
move(labc,xc,1,zc); //当只有一个盘子时直接从原柱移动到目的柱
settimectr(timect);
setcolorbak(labc,1);
}
else{
hanoi(labc,nc-1,xc,zc,yc);//当有N个盘子时,先把上面N-1个盘子移动到辅助的柱子上
setactcolor(labc,nc);
settimectr(timect);
move(labc,xc,nc,zc); //移动第N个盘子到目的柱
settimectr(timect);
setcolorbak(labc,nc);
hanoi(labc,nc-1,yc,xc,zc);//把剩下的N-1个盘子从辅助的柱子移动到目的柱
}
}
public void move(Label labb[],int xb,int nb,int zb) //移动操作方法
{ if(xb==140&&zb==660)
{labb[nb-1].setLocation(660-labb[nb-1].getWidth()/2,ch-50);
ah=ah+50;
ch=ch-50;
}
if(xb==140&&zb==400)
{labb[nb-1].setLocation(400-labb[nb-1].getWidth()/2,bh-50);
ah=ah+50;
bh=bh-50;
}
if(xb==400&&zb==660)
{labb[nb-1].setLocation(660-labb[nb-1].getWidth()/2,ch-50);
bh=bh+50;
ch=ch-50;
}
if(xb==400&&zb==140)
{labb[nb-1].setLocation(140-labb[nb-1].getWidth()/2,ah-50);
ah=ah-50;
}
if(xb==660&&zb==400)
{labb[nb-1].setLocation(400-labb[nb-1].getWidth()/2,bh-50);
ch=ch+50;
bh=bh-50;
}
if(xb==660&&zb==140)
{labb[nb-1].setLocation(140-labb[nb-1].getWidth()/2,ah-50);
ch=ch+50;
ah=ah-50;
}
}
}
汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺
猜你喜欢
转载自blog.csdn.net/zsx17/article/details/80647000
今日推荐
周排行