目录
1 算法与问题描述
1.1 问题描述
1.2 递归算法
1.3 非递归算法
2 游戏程序的总体设计
2.1 HannoiWindow类设计
2.2 Tower类设计
2.3 Disc类设计
2.4 TowerPoint类设计
2.5 HandleMouse类设计
2.6 AutoMoveDisc类
3 运行界面展示
4 总结
图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)任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。
定义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操作;
每次只关心上一层,上上层是到了上一层才考虑的事------递归
非递归方式即找规律:
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 与奇偶性 确定具体移动的步骤
在设计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 类之间的组合联系
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(); } }
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); } }
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; } }
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(); } }
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) { } }
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-1 选择级别界面
图3-2 高级玩法界面
图3-3 中级玩法自动演示界面
利用Java+swing实现界面,可利用鼠标事件进行操作盘子的移动,也可通过自动演示进行盘子的移动;
参考教程:Python 汉诺塔 | 菜鸟教程 (runoob.com)