目录
1 算法与问题描述
1.1 问题描述
图1-1 汉诺塔
假设有三个命名为a(TOWER 1),b(TOWER 2),c(TOWER 3)的塔座如图1-1所示,在塔座X上有n个直径大小各不相同,依次从小到大编号为1,2,3,...,n的圆盘。现要求将a塔座上的n个圆盘移到c塔座上并按同样顺序叠排, 圆盘移动时必须遵循下列规则:
(1)每次只能移动一个圆盘;
(2)圆盘可以插在a,b,c中的任意塔座上;
(3)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。
1.2 递归算法
定义N为圆盘数量:
当N=1时,A>C;
当N=2时,A>B | | A>C | | B>C;
当N=3时,A>C,A>B,C>B | | A>C | | B>A,B>C,A>C;
...
代码及代码思路:
public static void hanoi(int n,char a,char b,char c ) {
if(n==1) System.out.println(a+">"+c);
else {
//1
hanoi(n-1,a,c,b);
//2
System.out.println(a+">"+c);
//3
hanoi(n-1,b,a,c);
}
}
利用了分治法的思想
第一步 对于执行最大盘(N)到C的操作之前,即把盘(N-1)从A到B操作;
第二步 执行最大盘(N) 到C的操作;
第三步 对于执行最大盘(N)到C的操作之后,即把盘(N-1)从B到C操作;
每次只关心上一层,上上层是到了上一层才考虑的事------递归
1.3 非递归算法
非递归方式即找规律:
A号柱有n 个盘子,叫做源柱.移往C 号柱,叫做目的柱.B 号柱叫做中间柱.
全部移往C 号柱要f(n) =(2^n)- 1 次.
最大盘n 号盘在整个移动过程中只移动一次,n-1 号移动2 次,i 号盘移动
2^(n-i)次.
1 号盘移动次数最多,每2 次移动一次.
第2k+1 次移动的是1 号盘,且是第k+1 次移动1 号盘.
第4k+2 次移动的是2 号盘,且是第k+1 次移动2 号盘.
第(2^s)k+2^(s-1)次移动的是s 号盘,这时s 号盘已被移动了k+1 次.
每2^s 次就有一次是移动s 号盘.
第一次移动s 号盘是在第2^(s-1)次.
第二次移动s 号盘是在第2^s+2^(s-1)次.
第k+1 次移动s 号盘是在第k*2^s+2^(s-1)次.
A-->B,B-->C,C-->A叫做顺时针方向,A-->C,C-->B,B-->A叫做逆时针方向.
最大盘n 号盘只移动一次:A-->C它是逆时针移动.
n-1 移动2 次:A-->B,B-->C,是顺时针移动.
代码及代码思路:
public static void hanoi_f(int n) {
int s;// 从上到下几号盘
long i, t, k;
long res = (1 << n) - 1;
for (i = 1; i <= res; i++) {
for (t = 2, s = 1; s <= n; s++, t *= 2)
if (i % t == t / 2)
break;//找 第i步移动的s号盘
k = i / t;// 获得第s盘 第几次移动
if (n % 2 == s % 2) {// 逆时针
if ((k + 1) % 3 == 0)
System.out.println(s + " from B to A");
if ((k + 1) % 3 == 1)
System.out.println(s + " from A to c");
if ((k + 1) % 3 == 2)
System.out.println(s + " from C to B");
} else {// 顺时针
if ((k + 1) % 3 == 0)
System.out.println(s + " from C to A");
if ((k + 1) % 3 == 1)
System.out.println(s + " from A to B");
if ((k + 1) % 3 == 2)
System.out.println(s + " from B to C");
}
}
}
枚举 1, 2, 3, 4·····i, i+1, i+2, ·····步。
第一步 先获取第i步移动的几号盘,根据 (2^s)k+2^(s-1)=i,转化一下,满足 i%(2^s) =2^(s-1) ,令t=2^s;则有i%t=t/2;
第二步 再获得第S盘 第几次移动 ,根据 (2^s)k+2^(s-1)=i, k=i/(2^s) ,即 k=i/t;
第三步 最后根据周期T 与奇偶性 确定具体移动的步骤
2 游戏程序的总体设计
在设计hannoi塔时,需编写6个java源文件:HannoiWindow.java、Tower.java、TowerPoint.java、Disc.java、HandleMouse.java和AutoMoveDisc.java。
Hannoi塔除了要编写的6个Java源文件所给出的类外,还需要Java系统提供的一些重要的类,如JMenuBar、JMenu、JMenuItem和JButton。Hannoi塔所用到的一些重要的类以及之间的组合关系如图2-1所示:
图2-1 类之间的组合联系
2.1 HannoiWindow类设计
HannoiWindow类负责创建Hannoi塔的主窗口,该类含有main方法,Hannoi塔从该类开始执行。
HannoiWindow类的成员变量中有五种重要类型的对象、一个int基本型数据和一个char型数组。五种类型的对象分别是:Tower、JMenuBar、JMenu、JMenuItem和JButton对象。
事件实现窗口间的变化,根据变量amountOfDisc的不同更换游戏级别,即disc的个数;
代码:
package hannuota;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class HannoiWindow extends JFrame implements ActionListener {
Tower tower = null;
int amountOfDisc = 3;
char[] towerName = { 'A', 'B', 'C' };
JMenuBar bar;
JMenu menuGrade;
JMenuItem oneGradeItem, twoGradeItem, threeGradeItem;
JButton renew = null;
JButton autoButton = null;
JPanel center = new JPanel();
HannoiWindow() {
tower = new Tower(towerName);
tower.setAmountOfDisc(amountOfDisc);
tower.setMaxDiscWidth(120);
tower.setMinDiscWidth(50);
tower.setDiscHeight(16);
tower.putDiscOnTower();
add(tower, BorderLayout.CENTER);
bar = new JMenuBar();
menuGrade = new JMenu("选择级别");
oneGradeItem = new JMenuItem("初级");
twoGradeItem = new JMenuItem("中级");
threeGradeItem = new JMenuItem("高级");
menuGrade.add(oneGradeItem);
menuGrade.add(twoGradeItem);
menuGrade.add(threeGradeItem);
bar.add(menuGrade);
setJMenuBar(bar);
oneGradeItem.addActionListener(this);
twoGradeItem.addActionListener(this);
threeGradeItem.addActionListener(this);
renew = new JButton("重新开始");
renew.addActionListener(this);
autoButton = new JButton("自动演示");
autoButton.addActionListener(this);
JPanel north = new JPanel();
north.add(renew);
north.add(autoButton);
String mess = "将全部盘子从" + towerName[0] + "座搬运到" + towerName[1] + "座或" + towerName[2] + "座";
JLabel hintMess = new JLabel(mess, JLabel.CENTER);
north.add(hintMess);
add(north, BorderLayout.NORTH);
setResizable(false);
setVisible(true);
setBounds(60, 60, 460, 410);
//确保组件具有有效的布局
validate();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == oneGradeItem) {
amountOfDisc = 3;
tower.setAmountOfDisc(amountOfDisc);
tower.putDiscOnTower();
} else if (e.getSource() == twoGradeItem) {
amountOfDisc = 4;
tower.setAmountOfDisc(amountOfDisc);
tower.putDiscOnTower();
} else if (e.getSource() == threeGradeItem) {
amountOfDisc = 5;
tower.setAmountOfDisc(amountOfDisc);
tower.putDiscOnTower();
} else if (e.getSource() == renew) {
tower.setAmountOfDisc(amountOfDisc);
tower.putDiscOnTower();
} else if (e.getSource() == autoButton) {
tower.setAmountOfDisc(amountOfDisc);
tower.putDiscOnTower();
int x = this.getBounds().x + this.getBounds().width;
int y = this.getBounds().y;
tower.getAutoMoveDisc().setLocation(x, y);
tower.getAutoMoveDisc().setSize(280, this.getBounds().height);
tower.getAutoMoveDisc().setVisible(true);
}
validate();
}
public static void main(String args[]) {
new HannoiWindow();
}
}
2.2 Tower类设计
Tower类是javax.swing包中Jpanel容器的子类,创建的容器被添加到HannoiWindow窗口的中心。
Tower类的成员变量中有四种重要类型的对象、一个int基本型数据和一个char型数组。四种类型的对象分别是:Disc、TowerPoint、HandleMouse、和AutoMoveDisc对象。
代码:
package hannuota;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Tower extends JPanel {
int amountOfDisc = 3;
Disc[] disc;
int maxDiscWidth, minDiscWidth, discHeight;
char[] towerName;
TowerPoint[] pointA, pointB, pointC;
HandleMouse handleMouse;
AutoMoveDisc autoMoveDisc;
Tower(char[] towerName) {
handleMouse = new HandleMouse(this);
this.towerName = towerName;
setLayout(null);
setBackground(new Color(200, 226, 226));
}
public void setAmountOfDisc(int number) {
if (number <= 1)
amountOfDisc = 1;
else
amountOfDisc = number;
}
public void setMaxDiscWidth(int m) {
maxDiscWidth = m;
}
public void setMinDiscWidth(int m) {
minDiscWidth = m;
}
public void setDiscHeight(int h) {
discHeight = h;
}
public AutoMoveDisc getAutoMoveDisc() {
return autoMoveDisc;
}
public void putDiscOnTower() {
removeDisk();
int n = (maxDiscWidth - minDiscWidth) / amountOfDisc;
disc = new Disc[amountOfDisc];
for (int i = 0; i < disc.length; i++) {
disc[i] = new Disc();
disc[i].setNumber(i);
int diskwidth = minDiscWidth + i * n;//下面的disc 更宽
disc[i].setSize(diskwidth, discHeight);
disc[i].addMouseListener(handleMouse);
disc[i].addMouseMotionListener(handleMouse);
}
pointA = new TowerPoint[amountOfDisc];
pointB = new TowerPoint[amountOfDisc];
pointC = new TowerPoint[amountOfDisc];
int vertialDistance = discHeight;
for (int i = 0; i < pointA.length; i++) {
pointA[i] = new TowerPoint(maxDiscWidth, 100 + vertialDistance);
vertialDistance = vertialDistance + discHeight;
}
vertialDistance = discHeight;
for (int i = 0; i < pointB.length; i++) {
pointB[i] = new TowerPoint(2 * maxDiscWidth, 100 + vertialDistance);
vertialDistance = vertialDistance + discHeight;
}
vertialDistance = discHeight;
for (int i = 0; i < pointC.length; i++) {
pointC[i] = new TowerPoint(3 * maxDiscWidth, 100 + vertialDistance);
vertialDistance = vertialDistance + discHeight;
}
for (int i = 0; i < pointA.length; i++) {
pointA[i].putDisc(disc[i], this);
}
handleMouse.setPointA(pointA);
handleMouse.setPointB(pointB);
handleMouse.setPointC(pointC);
autoMoveDisc = new AutoMoveDisc(this);
autoMoveDisc.setTowerName(towerName);
autoMoveDisc.setAmountOfDisc(amountOfDisc);
autoMoveDisc.setPointA(pointA);
autoMoveDisc.setPointB(pointB);
autoMoveDisc.setPointC(pointC);
validate();
repaint();
}
public void removeDisk() {
if (pointA != null) {
for (int i = 0; i < pointA.length; i++) {
pointA[i].removeDisc(pointA[i].getDiscOnPoint(), this);
pointB[i].removeDisc(pointB[i].getDiscOnPoint(), this);
pointC[i].removeDisc(pointC[i].getDiscOnPoint(), this);
}
}
}
//awt 中画板
public void paintComponent(Graphics g) {
super.paintComponent(g);
int x1, y1, x2, y2;
x1 = pointA[0].getX();
y1 = pointA[0].getY() - discHeight / 2;
x2 = pointA[amountOfDisc - 1].getX();
y2 = pointA[amountOfDisc - 1].getY() + discHeight / 2;
g.drawLine(x1, y1, x2, y2);//划线
x1 = pointB[0].getX();
y1 = pointB[0].getY() - discHeight / 2;
x2 = pointB[amountOfDisc - 1].getX();
y2 = pointB[amountOfDisc - 1].getY() + discHeight / 2;
g.drawLine(x1, y1, x2, y2);
x1 = pointC[0].getX();
y1 = pointC[0].getY() - discHeight / 2;
x2 = pointC[amountOfDisc - 1].getX();
y2 = pointC[amountOfDisc - 1].getY() + discHeight / 2;
g.drawLine(x1, y1, x2, y2);
g.setColor(Color.blue);
x1 = pointA[amountOfDisc - 1].getX() - maxDiscWidth / 2;
y1 = pointA[amountOfDisc - 1].getY() + discHeight / 2;
x2 = pointC[amountOfDisc - 1].getX() + maxDiscWidth / 2;
y2 = pointC[amountOfDisc - 1].getY() + discHeight / 2;
int length = x2 - x1, height = 6;
g.fillRect(x1, y1, length, height);//填充矩形
int size = 5;
for (int i = 0; i < pointA.length; i++) {
//缩短 width和height 画点
g.fillOval(pointA[i].getX() - size / 2, pointA[i].getY() - size / 2, size, size);
g.fillOval(pointB[i].getX() - size / 2, pointB[i].getY() - size / 2, size, size);
g.fillOval(pointC[i].getX() - size / 2, pointC[i].getY() - size / 2, size, size);
}
//画字符串
g.drawString(towerName[0] + "座", pointA[amountOfDisc - 1].getX(), pointA[amountOfDisc - 1].getY() + 50);
g.drawString(towerName[1] + "座", pointB[amountOfDisc - 1].getX(), pointB[amountOfDisc - 1].getY() + 50);
g.drawString(towerName[2] + "座", pointC[amountOfDisc - 1].getX(), pointC[amountOfDisc - 1].getY() + 50);
}
}
2.3 Disc类设计
Disc类是javax.swing包中JButton类的子类,所创建的对象称作Hannoi塔中的“盘子”。
Tower类有Disc类型的数组disc。disc数组的单元是用Disc创建的对象,被放置在Tower所创建的容器tower中,用来表示tower中的盘。
代码:
package hannuota;
import java.awt.Color;
import javax.swing.JButton;
public class Disc extends JButton {
int number;
TowerPoint point;
Disc() {
setBackground(Color.cyan);
}
public void setNumber(int n) {
number = n;
}
public int getNumber() {
return number;
}
public void setPoint(TowerPoint p) {
point = p;
}
public TowerPoint getPoint() {
return point;
}
}
2.4 TowerPoint类设计
TowerPoint类负责在Tower中创建表示位置的塔点对象。
TowerPoint所创建的对象将作为Tower类中TowerPoint型数组pointA、pointB和pointC中的元素。
代码:
package hannuota;
import java.awt.Component;
import java.awt.Container;
public class TowerPoint {
int x, y;
boolean haveDisc;
Disc disc = null;
public TowerPoint(int x, int y) {
this.x = x;
this.y = y;
}
public boolean isHaveDisc() {
return haveDisc;
}
public void setHaveDisc(boolean boo) {
haveDisc = boo;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public boolean equals(TowerPoint p) {
if (p.getX() == this.getX() && p.getY() == this.getY())
return true;
else
return false;
}
public void putDisc(Component com, Container con) {
disc = (Disc) com;
con.setLayout(null);
con.add(disc);
int w = disc.getBounds().width;
int h = disc.getBounds().height;
disc.setBounds(x - w / 2, y - h / 2, w, h);
haveDisc = true;
disc.setPoint(this);
con.validate();
}
public Disc getDiscOnPoint() {
return disc;
}
//refresh
public void removeDisc(Component com, Container con) {
if (com != null)
con.remove(com);
con.validate();
}
}
2.5 HandleMouse类设计
HandleMouse类创建的对象负责处理鼠标事件。
HandleMouse类实现了MouseListener和MouseMotionListener接口,创建的对象handleMouse是tower容器的成员之一,负责监视tower容器中Disc盘子对象上的鼠标事件。
当用户用鼠标单击tower中的盘子,并拖动鼠标时,handleMouse对象负责给出移动盘子的有关算法。重写了mousePressed、mouseDragged、mouseReleased等方法;
代码:
package hannuota;
import java.awt.Container;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
//cxsjjssj程序设计基础设计
public class HandleMouse implements MouseListener, MouseMotionListener {
TowerPoint[] pointA, pointB, pointC;
TowerPoint startPoint = null, endPoint = null;
int leftX, leftY, x0, y0;
boolean move = false, countTime = false;
Container con;
HandleMouse(Container con) {
this.con = con;
}
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 mousePressed(MouseEvent e) {
move = false;
Disc disc = null;
disc = (Disc) e.getSource();
startPoint = disc.getPoint();
x0 = e.getX();
y0 = e.getY();
int m = 0;
for (int i = 0; i < pointA.length; i++) {
if (pointA[i].equals(startPoint)) {
m = i;
if (m > 0 && (pointA[m - 1].isHaveDisc() == false)) {
move = true;
break;
} else if (m == 0) {
move = true;
break;
}
}
}
for (int i = 0; i < pointB.length; i++) {
if (pointB[i].equals(startPoint)) {
m = i;
if (m > 0 && (pointB[m - 1].isHaveDisc() == false)) {
move = true;
break;
} else if (m == 0) {
move = true;
break;
}
}
}
for (int i = 0; i < pointC.length; i++) {
if (pointC[i].equals(startPoint)) {
m = i;
if (m > 0 && (pointC[m - 1].isHaveDisc() == false)) {
move = true;
break;
} else if (m == 0) {
move = true;
break;
}
}
}
}
//鼠标移动MouseMotionListener
public void mouseMoved(MouseEvent e) {
}
//鼠标拖动MouseMotionListener
public void mouseDragged(MouseEvent e) {
Disc disc = null;
disc = (Disc) e.getSource();
leftX = disc.getBounds().x;
leftY = disc.getBounds().y;
int x = e.getX();
int y = e.getY();
leftX = leftX + x;
leftY = leftY + y;
if (move == true)
disc.setLocation(leftX - x0, leftY - y0);
}
//鼠标释放
public void mouseReleased(MouseEvent e) {
Disc disc = null;
disc = (Disc) e.getSource();
//矩形类
Rectangle rect = disc.getBounds();
boolean location = false;
int x = -1, y = -1;
for (int i = 0; i < pointA.length; i++) {
x = pointA[i].getX();
y = pointA[i].getY();
if (rect.contains(x, y)) {
endPoint = pointA[i];
if (i == pointA.length - 1 && endPoint.isHaveDisc() == false) {
location = true;
break;
} else if (i < pointA.length - 1 && pointA[i + 1].isHaveDisc() == true && endPoint.isHaveDisc() == false
&& pointA[i + 1].getDiscOnPoint().getNumber() > disc.getNumber()) {
location = true;
break;
}
}
}
for (int i = 0; i < pointB.length; i++) {
x = pointB[i].getX();
y = pointB[i].getY();
if (rect.contains(x, y)) {
endPoint = pointB[i];
if (i == pointB.length - 1 && endPoint.isHaveDisc() == false) {
location = true;
break;
} else if (i < pointB.length - 1 && pointB[i + 1].isHaveDisc() == true && endPoint.isHaveDisc() == false
&& pointB[i + 1].getDiscOnPoint().getNumber() > disc.getNumber()) {
location = true;
break;
}
}
}
for (int i = 0; i < pointC.length; i++) {
x = pointC[i].getX();
y = pointC[i].getY();
if (rect.contains(x, y)) {
endPoint = pointC[i];
if (i == pointC.length - 1 && endPoint.isHaveDisc() == false) {
location = true;
break;
} else if (i < pointC.length - 1 && pointC[i + 1].isHaveDisc() == true && endPoint.isHaveDisc() == false
&& pointC[i + 1].getDiscOnPoint().getNumber() > disc.getNumber()) {
location = true;
break;
}
}
}
if (endPoint != null && location == true) {
endPoint.putDisc(disc, con);
startPoint.setHaveDisc(false);
} else
startPoint.putDisc(disc, con);
}
//鼠标进入
public void mouseEntered(MouseEvent e) {
}
//鼠标离开
public void mouseExited(MouseEvent e) {
}
//鼠标单击
public void mouseClicked(MouseEvent e) {
}
}
2.6 AutoMoveDisc类
AutoMoveDisc类创建的对象负责自动移动盘子从一个座到另一个座。
AutoMoveDisc类实现了ActionListener接口,创建的对象autoMoveDisc是Tower的成员之一。
代码:
package hannuota;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.Timer;
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;
Timer time;
int i = 0, number = 0;
AutoMoveDisc(Container con) {
setModal(true);
setTitle("自动演示搬盘子过程");
this.con = con;
moveStep = new StringBuffer();
time = new Timer(100, this);
time.setInitialDelay(10);
showStep = new JTextArea(10, 12);
bStart = new JButton("演示");
bStop = new JButton("暂停");
bContinue = new JButton("继续");
bClose = new JButton("关闭");
bStart.addActionListener(this);
bStop.addActionListener(this);
bContinue.addActionListener(this);
bClose.addActionListener(this);
JPanel south = new JPanel();
south.setLayout(new FlowLayout());
south.add(bStart);
south.add(bStop);
south.add(bContinue);
south.add(bClose);
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);
}
}
//key 算法
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);
}
}
}
3 运行界面展示
图3-1 选择级别界面
图3-2 高级玩法界面
图3-3 中级玩法自动演示界面
4 总结
利用Java+swing实现界面,可利用鼠标事件进行操作盘子的移动,也可通过自动演示进行盘子的移动;
参考教程:Python 汉诺塔 | 菜鸟教程 (runoob.com)