还有个“自动演示”的类,AutoMoveDisc.java
这个类还没完全看完,涉及到hannio塔的算法问题了
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
public class AutoMoveDisc extends JDialog implements ActionListener{
int amountOfDisc=3;
TowerPoint [] pointA,pointB,pointC;
char [] towerName;
Container con;
StringBuffer moveStep;
JTextArea showStep;
JButton bStart,bStop,bContinue,bClose,bSave;
Timer time;
FileDialog saveDlg;/////////////////////////
int i=0,number=0;
AutoMoveDisc(Container con){
setModal(true);
setTitle("自动演示搬盘子过程");
this.con=con;
moveStep=new StringBuffer();
time=new Timer(1000,this);
time.setInitialDelay(10);
showStep=new JTextArea(10,12);
bStart=new JButton("演示");
bStop=new JButton("暂停");
bContinue=new JButton("继续");
bClose=new JButton("关闭");
bSave=new JButton("保存");
bStart.addActionListener(this);
bStop.addActionListener(this);
bContinue.addActionListener(this);
bClose.addActionListener(this);
bSave.addActionListener(this);
JPanel south=new JPanel();
south.setLayout(new FlowLayout());
south.add(bStart);
south.add(bStop);
south.add(bContinue);
south.add(bSave);
south.add(bClose);
saveDlg=new FileDialog(this,"保存到文件",FileDialog.SAVE);
saveDlg.setVisible(false);
saveDlg.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
saveDlg.setVisible(false);
}
});
add(new JScrollPane(showStep),BorderLayout.CENTER);
add(south,BorderLayout.SOUTH);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
towerName=new char[3];
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
time.stop();
setVisible(false);
}
});
}
public void setPointA(TowerPoint [] pointA){
this.pointA=pointA;
}
public void setPointB(TowerPoint [] pointB){
this.pointB=pointB;
}
public void setPointC(TowerPoint [] pointC){
this.pointC=pointC;
}
public void setTowerName(char name[]){
if(name[0]==name[1]||name[0]==name[2]||name[1]==name[2]){
towerName[0]='A';
towerName[1]='B';
towerName[2]='C';
}
else
towerName=name;
}
public void setAmountOfDisc(int n){
amountOfDisc=n;
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==time){
number++;
char cStart,cEnd;
if(i<=moveStep.length()-2){
cStart=moveStep.charAt(i);
cEnd=moveStep.charAt(i+1);
showStep.append("("+number+")从"+cStart+"座搬一个盘子到"+cEnd+"座\n");
autoMoveDisc(cStart,cEnd);
}
i=i+2;
if(i>=moveStep.length()-1){
time.stop();
}
}
else if(e.getSource()==bStart){
if(moveStep.length()==0){
if(time.isRunning()==false){
i=0;
moveStep=new StringBuffer();
setMoveStep(amountOfDisc,towerName[0],towerName[1],towerName[2]);
number=0;
time.start();
}
}
}
else if(e.getSource()==bStop){
if(time.isRunning()==true)
time.stop();
}
else if(e.getSource()==bContinue){
if(time.isRunning()==false)
time.restart();
}
else if(e.getSource()==bClose){
time.stop();
setVisible(false);
}
else if(e.getSource()==bSave)
{
saveDlg.setVisible(true);
if(saveDlg.getFile()!=null)
{
try
{
File file=new File(saveDlg.getDirectory(),saveDlg.getFile());
FileWriter tofile=new FileWriter(file);
BufferedWriter out=new BufferedWriter(tofile);
out.write(showStep.getText(),0,(showStep.getText()).length());
out.close();
tofile.close();
}
catch(IOException e2)
{
}
}
}
}
private void setMoveStep(int amountOfDisc,char one,char two,char three){
if(amountOfDisc==1){
moveStep.append(one);
moveStep.append(three);
}
else{
setMoveStep(amountOfDisc-1,one,three,two);
moveStep.append(one);
moveStep.append(three);
setMoveStep(amountOfDisc-1,two,one,three);
}
}
private void autoMoveDisc(char cStart,char cEnd){
Disc disc=null;
if(cStart==towerName[0]){
for(int i=0;i<pointA.length;i++){
if(pointA[i].isHaveDisc()==true){
disc=pointA[i].getDiscOnPoint();
pointA[i].setHaveDisc(false);
break;
}
}
}
if(cStart==towerName[1]){
for(int i=0;i<pointB.length;i++){
if(pointB[i].isHaveDisc()==true){
disc=pointB[i].getDiscOnPoint();
pointB[i].setHaveDisc(false);
break;
}
}
}
if(cStart==towerName[2]){
for(int i=0;i<pointC.length;i++){
if(pointC[i].isHaveDisc()==true){
disc=pointC[i].getDiscOnPoint();
pointC[i].setHaveDisc(false);
break;
}
}
}
TowerPoint endPoint=null;
int i=0;
if(cEnd==towerName[0]){
for(i=0;i<pointA.length;i++){
if(pointA[i].isHaveDisc()==true){
if(i>0){ endPoint=pointA[i-1];
break;
}
else if(i==0)
break;
}
}
if(i==pointA.length)
endPoint=pointA[pointA.length-1];
}
if(cEnd==towerName[1]){
for(i=0;i<pointB.length;i++){
if(pointB[i].isHaveDisc()==true){ if(i>0){ endPoint=pointB[i-1];
break;
}
else if(i==0)
break;
}
}
if(i==pointB.length)
endPoint=pointB[pointB.length-1];
}
if(cEnd==towerName[2]){
for(i=0;i<pointC.length;i++){
if(pointC[i].isHaveDisc()==true){ if(i>0){ endPoint=pointC[i-1];
break;
}
else if(i==0)
break;
}
}
if(i==pointC.length)
endPoint=pointC[pointC.length-1];
}
if(endPoint!=null&&disc!=null){
endPoint.putDisc(disc,con);
endPoint.setHaveDisc(true);
}
}
}
一下是要增加的功能我自己写的类,包括对以上7个主类的修改:
首先是设置盘子最大、最小宽度以及高度的类SetDiscWidthDlg.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SetDiscWidthDlg extends Dialog implements ActionListener
{
Tower tower;
JTextField maxtext,mintext,heighttext;
JButton sure,cancel;
GridLayout grid;
SetDiscWidthDlg(JFrame f,Tower tower)
{
super(f,"设置盘子大小",true);
this.tower=tower;
maxtext=new JTextField(5);
mintext=new JTextField(5);
heighttext=new JTextField(5);
sure=new JButton("确定");
cancel=new JButton("退出");
sure.addActionListener(this);
cancel.addActionListener(this);
grid=new GridLayout(4,2);
setLayout(grid);
add(new JLabel("最大宽度(像素)"));add(maxtext);
add(new JLabel("最小宽度(像素)"));add(mintext);
add(new JLabel("盘子高度(像素)"));add(heighttext);
add(sure);add(cancel);
setBounds(100,100,200,200);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
setVisible(false);
}
});
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==sure)
{
try
{
tower.maxDiscWidth=Integer.valueOf(maxtext.getText());
tower.minDiscWidth=Integer.valueOf(mintext.getText());
tower.discHeight=Integer.valueOf(heighttext.getText());
tower.setMaxDiscWidth(tower.maxDiscWidth);
tower.setMinDiscWidth(tower.minDiscWidth);
tower.setDiscHeight(tower.discHeight);
tower.putDiscOnTower();
validate();
}
catch(NumberFormatException en)
{
maxtext.setText("请输入数字");
}
}
if(e.getSource()==cancel)
{
setVisible(false);
}
}
}
这里其实还有点没实现,既每次设置完后,Tower都会重新开始,既不能再游戏的过程中间设置。
也就是说必须在游戏开始之前设置
尚需努力啊!
接下来是设置盘子数量的类SetDiscAcountDlg.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SetDiscAcountDlg extends Dialog implements ActionListener
{
JButton sure,cancel;
Tower tower;
JTextField text;
SetDiscAcountDlg(JFrame f,Tower tower)
{
super(f,"设置盘子数目",true);
this.tower=tower;
Box box1=Box.createVerticalBox();
sure=new JButton("确定");
cancel=new JButton("退出");
text=new JTextField(5);
Box box2=Box.createHorizontalBox();
box2.add(sure);
box2.add(cancel);
box1.add(new JLabel("请输入0-13之间的数"));
box1.add(text);
box1.add(box2);
add(box1);
setBounds(100,100,210,100);
sure.addActionListener(this);
cancel.addActionListener(this);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
setVisible(false);
}
});
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==sure)
{
try
{
tower.amountOfDisc=Integer.valueOf(text.getText());
if(tower.amountOfDisc>0&&tower.amountOfDisc<13)
{
tower.setAmountOfDisc(tower.amountOfDisc);
tower.putDiscOnTower();
}
else
text.setText("请输入范围内的数字");
}
catch(NumberFormatException en)
{
text.setText("请输入数字(每个选项)");
}
}
if(e.getSource()==cancel)
{
setVisible(false);
}
}
}
关于这个类,在主类就提到了,amountOfDisc这个变量的问题,纠结了好久才搞清楚。
最后是一个设置颜色的类SetDiscColorDlg.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class SetDiscColorDlg extends Dialog implements ActionListener
{
Tower tower;
JTextField maxtext,mintext,heighttext;
JButton bgcolor,color,cancel;
SetDiscColorDlg(JFrame f,Tower tower)
{
super(f,"设置颜色",true);
setLayout(new FlowLayout());
this.tower=tower;
bgcolor=new JButton("设置背景颜色");
color=new JButton("设置盘子颜色");
cancel=new JButton(" 退出 ");
add(bgcolor);
add(color);
add(cancel);
bgcolor.addActionListener(this);
color.addActionListener(this);
cancel.addActionListener(this);
setBounds(100,100,200,200);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
setVisible(false);
}
});
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==bgcolor)
{
Color newColor=JColorChooser.showDialog(this,"选择背景色",new Color(200,226,226));
tower.setBackground(newColor);
}
else if(e.getSource()==color)
{
Color newColor=JColorChooser.showDialog(this,"选择背景色",new Color(200,226,226));
tower.color=newColor;
tower.putDiscOnTower();
}
else if(e.getSource()==cancel)
{
setVisible(false);
}
}
}
这个类也和设置盘子大小的类有个同样的美能达到的地方,就是必须在游戏开始之前设置,不能再游戏的过程中设置,否则将重新开始。
总之自己写的东西缺陷很多,很繁琐,思路不够清晰,自己的思维不够开放,还要多多努力了!