import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class Hanoi extends JFrame {
DrawPanel panel = new DrawPanel(3);
ButtonPanel panel2 = new ButtonPanel();
KeyBoardListener keyboardlistener = new KeyBoardListener(panel);
public Hanoi() {
this.setFocusable(true);
panel.setBounds(2,2,2,2);
panel.setBorder(BorderFactory.createLineBorder(Color.black));
ButtonPanel.start.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
panel.refresh(3);
}
});
ButtonPanel.quit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int res;
res = JOptionPane.showConfirmDialog(null,"确定退出?","退出",JOptionPane.YES_NO_OPTION);
if(res == JOptionPane.YES_OPTION) {
System.exit(0);
}
}
});
ButtonPanel.help.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null,"将所有盘子移动到最后一个柱子上,通过键盘上下左右键操作。另外请注意每一关都是有步数限制的");
}
});
add(panel,BorderLayout.CENTER);
add(panel2,BorderLayout.EAST);
this.addKeyListener(keyboardlistener);
ButtonPanel.start.addKeyListener(keyboardlistener);
ButtonPanel.help.addKeyListener(keyboardlistener);
ButtonPanel.quit.addKeyListener(keyboardlistener);
}
public static void main(String[] args) {
Hanoi frame = new Hanoi();
frame.setTitle("汉诺塔");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,309);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
//键盘监听器
class KeyBoardListener extends KeyAdapter {
DrawPanel panel;
KeyBoardListener(DrawPanel panel) {
this.panel = panel;
}
public void keyPressed(KeyEvent e) {
int n = e.getKeyCode();
if(n == 38) {
panel.getPlate();
} else if(n == 40) {
panel.setPlate();
} else if(n == 39) {
panel.movePlateRight();
} else if(n == 37) {
panel.movePlateLeft();
}
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
//图形界面模块
class DrawPanel extends JPanel {
ArrayList<Plate> plates = new ArrayList<Plate>();//盘子
static Pillar[] pillars = new Pillar[3];//柱子
Hand hand = new Hand(1);//抓取工具
int chosen;//被抓起的盘子id
int n;//盘子个数
boolean init;//初始化判断
int step;//步数
static {
for(int i=0;i<3;i++) {
pillars[i] = new Pillar(i+1);
}
}
//构造方法
DrawPanel(int a) {
init = true;
this.refresh(a);
}
//刷新
public void refresh(int a) {
n = a;
cleanUp();
Plate[] temp = new Plate[a];
int i;
for(i=1;i<a+1;i++) {
temp[i-1] = new Plate(i);
temp[i-1].pillarid = 1;
temp[i-1].position = a-i+1;
pillars[0].count++;
pillars[0].plateid[temp[i-1].position] = temp[i-1].id;
plates.add(temp[i-1]);
}
if(!init) {
repaint();
} else {
init = false;
}
}
//清空柱子
public void cleanUp() {
int i ,j;
step = 0;
hand.pillarid = 1;
hand.empty = true;
plates.clear();
for(i=0;i<3;i++) {
for(j=0;j<pillars[i].count;j++) {
pillars[i].plateid[j+1] = 0;
}
pillars[i].count = 0;
}
}
//绘图
public void paintComponent(Graphics g) {
super.paintComponent(g);
int x = getWidth();
int y = getHeight();
int[] a = {hand.pillarid*x/4-10,hand.pillarid*x/4+10,hand.pillarid*x/4,hand.pillarid*x/4-10};
int[] b = {10,10,20,10};
String[] string = new String[]{"一","二","三","四","五","六","七"};
int i;
for(i=1;i<4;i++) {
g.drawRoundRect(i*x/4-3,y-240,6,250,2,2);
}
for(i=0;i<n;i++) {
g.fillRoundRect(plates.get(i).pillarid*x/4-plates.get(i).width/2,y-10*plates.get(i).position,plates.get(i).width,10,2,2);
}
g.drawPolyline(a,b,a.length);
g.drawString("步数:"+step,10,20);
g.drawString("第"+string[n-3]+"关",350,20);
}
//判断超过步数
void judge() {
int h = (int)(((Math.pow(2,n)-1)*2-1)*1.5);
if(step == h) {
JOptionPane.showMessageDialog(null,"超过了限制步数,请再接再厉!");
refresh(3);
}
}
//向右移动
void movePlateRight() {
hand.pillarid = hand.pillarid%3+1;
if(chosen != 0) {
plates.get(chosen-1).pillarid = plates.get(chosen-1).pillarid %3+1;
}
step++;
repaint();
judge();
}
//向左移动
void movePlateLeft() {
hand.pillarid = (hand.pillarid+1)%3+1;
if(chosen != 0) {
plates.get(chosen-1).pillarid = (plates.get(chosen-1).pillarid+1)%3+1;
}
step++;
repaint();
judge();
}
//放下盘子
void setPlate() {
if(!hand.empty) {
int m;
m = pillars[hand.pillarid-1].plateid[pillars[hand.pillarid-1].count];
if(chosen < m||m == 0) {
plates.get(chosen-1).position = pillars[hand.pillarid-1].count+1;
pillars[hand.pillarid-1].plateid[pillars[hand.pillarid-1].count+1] = chosen;
pillars[hand.pillarid-1].count++;
chosen = 0;
hand.empty = true;
repaint();
if(pillars[2].count == n) {
if(n == 9) {
JOptionPane.showMessageDialog(null,"太棒了!你完成了所有关卡!");
System.exit(0);
}
JOptionPane.showMessageDialog(null,"恭喜你,成功了!进入下一关!");
n++;
refresh(n);
}
}
}
}
//抓起盘子
void getPlate() {
if(hand.empty) {
int m;
if(pillars[hand.pillarid-1].count != 0) {
m = pillars[hand.pillarid-1].plateid[pillars[hand.pillarid-1].count];
plates.get(m-1).position = 25;
pillars[hand.pillarid-1].plateid[pillars[hand.pillarid-1].count] = 0;
pillars[hand.pillarid-1].count--;
chosen = m;
hand.empty = false;
repaint();
}
}
}
}
//按钮模块
class ButtonPanel extends JPanel {
static JButton help = new JButton("帮助");
//static JButton setting = new JButton("设置");
static JButton start = new JButton("重新开始");
static JButton quit = new JButton("退出");
static JLabel icon = new JLabel();
public ButtonPanel() {
setLayout(new GridLayout(4,1,0,0));
setBounds(20,0,20,0);
this.add(icon);
this.add(start);
this.add(help);
this.add(quit);
}
}
//柱子
class Pillar {
int id;
int count;
int height = 240;
int width = 6;
int[] plateid;
Color color;
Pillar(int n) {
id = n;
count = 0;
plateid = new int[20];
}
}
//盘子
class Plate {
int id;
int height = 10;
int width;
int pillarid;
int position;
Color color;
Plate(int n) {
id = n;
width = 2*(id*5+3);
}
}
//抓取工具
class Hand {
int pillarid;
int[] x = {};
int[] y = {};
boolean empty;
Color color;
Hand(int n) {
pillarid = n;
empty = true;
}
}
汉诺塔游戏是一种经典的逻辑谜题,源自印度的传说,由三个柱子和一堆大小不一的圆盘组成。游戏的目标是将所有圆盘从一个柱子(起始柱)移动到另一个柱子(目标柱),同时遵守以下规则: 1. **每次只能移动一个圆盘**,不能同时移动多个。 2. **大盘子不能放在小盘子之上**,即任何时候大盘子都不能位于小盘子之上。 在Java中实现汉诺塔游戏,主要涉及到递归算法的应用。汉诺塔问题的解决方案可以通过将大问题分解为小问题来解决,也就是将n个圆盘从起始柱A通过中间柱B移动到目标柱C的过程可以分为三步: 1. **将n-1个圆盘从A移动到B**,此时目标柱C是空的,不需要担心大盘子压住小盘子的问题。 2. **将剩下的一个圆盘从A直接移动到C**,这是最简单的一次移动。 3. **将B上的n-1个圆盘借助A移动到C**,现在A柱是空的,可以作为辅助柱。 这个过程可以用递归函数来表示,递归函数的基本结构如下: ```java void hanoi(int n, char from_rod, char aux_rod, char to_rod) { if (n >= 1) { hanoi(n - 1, from_rod, to_rod, aux_rod); move_disk(from_rod, to_rod); hanoi(n - 1, aux_rod, from_rod, to_rod); } } ``` 在这个函数中,`n`代表圆盘数量,`from_rod`、`aux_rod`和`to_rod`分别代表起始柱、辅助柱和目标柱。`move_disk`函数用于实际的圆盘移动操作,通常会打印出移动的信息。 为了使程序更具交互性,你可以添加用户输入处理,比如让用户选择开始游戏、查看帮助或者退出等。此外,可以使用图形界面(如Swing或JavaFX)来创建更直观的游戏体验,使得用户可以直接通过点击按钮来移动圆盘。 在提供的压缩包文件中,`Hanoi`可能包含的是Java源代码文件(`.java`),以及编译后的可执行文件(`.exe`)。源代码文件通常会包含上述的递归函数实现,以及游戏的主程序入口和用户交互逻辑。可执行文件则允许用户在没有安装Java开发环境的情况下直接运行游戏。 学习这个项目可以帮助初学者理解递归算法和Java编程的基本概念,同时也能提升问题解决和逻辑思维能力。在实际编程过程中,可以尝试优化代码,例如增加错误处理,提高用户界面的友好性,或者引入更复杂的圆盘数量和游戏模式,来增加挑战性和趣味性。












- 1

- #完美解决问题
- #运行顺畅
- #内容详尽
- #全网独家
- #注释完整
- qq_222944292014-11-12可以直接用,比较简单,不过不能设置阶数
- ding_10172015-12-18内容比较好,可以直接用,没有错误,很值得学习

- 粉丝: 1
- 资源: 4
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助


最新资源
- 精品系列(49).pptx
- 精品系列(56).pptx
- 精品系列(54).pptx
- 精品系列(59).pptx
- 精品系列(57).pptx
- 精品系列(58).pptx
- 思科-300-420 (351 Questions).pdf
- 【任务分配】基于matlab电池感知层次结构任务分配中分配【含Matlab源码 13073期】.zip
- 【任务分配】基于matlab大规模多代理系统中的任务分配【含Matlab源码 13078期】.zip
- 【任务分配】基于matlab动态无向图分布式k-wta性能评估及任务分配【含Matlab源码 13072期】.zip
- 【任务分配】基于matlab风险自适应任务分配【含Matlab源码 13076期】.zip
- 【任务分配】基于matlab蚁群算法ACO无人机任务分配【含Matlab源码 13077期】.zip
- 【物理应用】基于matlab火箭喷管发散段设计特征线法MoC【含Matlab源码 13071期】.zip
- 嵌入式15届蓝桥杯省题自用(4T84.1分)
- CISSP-Glossary-Booklet-1st-Editi.pdf
- F5 101VCE格式.vce


