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;
}
}