游戏介绍
游戏来源
汉诺塔的传说
汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
假如每秒钟一次,共需多长时间呢?移完这些金片需要5845.54亿年以上,太阳系的预期寿命据说也就是数百亿年。真的过了5845.54亿年,地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭。
游戏地址
汉诺塔游戏:http://ertong.973.com/p114895
浏览器要用360或搜狗等国产浏览器,应该还需要安装flash。此外在苹果的iPad应用商店也有这款游戏
算法实现
算法归类
属于分治算法
算法思路
- 问题1
如果只有一个圆盘,直接将圆盘从塔A移动到塔C
- 问题2
如果有两个圆盘,先将第一个圆盘移动到暂存塔B,然后将第二个圆盘移动到目标塔C,最后将第一个圆盘从暂存盘B移动到目标塔C
- 问题3
如果有三个圆盘,将上面的两个圆盘看成一个整体H,最下面的圆盘是一个单独的圆盘m。H需要移动到暂存塔B,m移动到目标塔C,这样就和问题2相似。此时再考虑将H移动到塔B的方式,同样,将H分为两部分,上面的一部分和下面的一部分,此时,塔B就成了H的目标塔,塔C就成了H的暂存塔,转到了问题2的解决思路
代码实现
package algorithm;
import java.util.LinkedList;
import java.util.Scanner;
/**
*
* @Description 汉诺塔游戏
* @author ningqian QQ:2587658527
* @version
* @date 2021年3月18日下午9:27:08
*/
public class HanNuoTower {
private int NumOfPlate;// 圆盘的数量
private Tower towerA;
private Tower towerB;
private Tower towerC;
private int count;// 记录移动圆盘的步数
public static void main(String[] args) {
System.out.println("开始汉诺塔游戏~");
HanNuoTower towerGame = new HanNuoTower();
Scanner scan = new Scanner(System.in);
System.out.println("请输入要移动圆盘的个数");
int n = scan.nextInt();
// 设置圆盘的个数
towerGame.setNumOfPlate(n);
// 开始移动
towerGame.autoMove();
}
// 构造器,创建游戏的同时,创建三个塔
public HanNuoTower() {
super();
towerA = new Tower("A");
towerB = new Tower("B");
towerC = new Tower("C");
}
//获得圆盘的总个数
public int getNumOfPlate() {
return NumOfPlate;
}
//根据输入的名字返回对应的汉诺塔
public Tower getTower(String s) {
if (s.equals("A")) {
return towerA;
} else if (s.equals("B")) {
return towerB;
} else {
return towerC;
}
}
//在初始化游戏时设置圆盘的个数
public void setNumOfPlate(int numOfPlate) {
NumOfPlate = numOfPlate;
String s = "";
// 先将所有的盘都放到A塔
//用*的个数表示圆盘的大小
for (int i = 0; i < numOfPlate; i++) {
s += "*";
}
for (int i = 0; i < numOfPlate; i++) {
towerA.push(s.substring(i));
}
count = 0;
}
// 显示三个塔的圆盘信息
public int getCount() {
return count;
}
public void showTower() {
System.out
.println("-----------------" + "第 " + getCount() + " 次移动" + "---------------------------------------");
System.out.println(towerA);
System.out.println(towerB);
System.out.println(towerC);
System.out.println("-------------------" + "结束移动" + "----------------------------------------");
}
// 移动圆盘
public void move(int num, Tower tower1, Tower tower2) {
System.out.println("将第 " + num + " 个圆盘从塔 " + tower1.getName() + " 移动到塔 " + tower2.getName() + " :");
tower2.push(tower1.pop());
count++;// 移动次数加一
showTower();// 每移动一个圆盘就显示移动结束后三个盘的信息
}
// 汉诺塔游戏的整个移动过程
public void autoMove(int num, Tower tower1, Tower tower2, Tower tower3) {
if (num == 1) {
move(num, tower1, tower3);
} else {
num--;
autoMove(num, tower1, tower3, tower2);
move(num + 1, tower1, tower3);
autoMove(num, tower2, tower1, tower3);
}
}
// 重载
public void autoMove() {
autoMove(getNumOfPlate(), getTower("A"), getTower("B"), getTower("C"));
System.out.println("恭喜!游戏过关成功");
}
}
class Tower {
private String name; // 表示每个塔的名字
private LinkedList<String> plateList; // 存放圆盘的列表 栈的形式
// 构造器,每创建一个塔,赋一个名字
public Tower(String name) {
super();
this.name = name;
plateList = new LinkedList<String>();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 添加盘
public void push(String plate) {
plateList.push(plate);
}
// 移除盘
public String pop() {
return plateList.pop();
}
// 返回塔中圆盘的个数
public int numOfTower() {
return plateList.size();
}
@Override
public String toString() {
return "Tower(塔顶->塔底) name=" + name + ", plateList=" + plateList + "," + " nums:" + numOfTower();
}
}