📄 hanoi11.java
字号:
/**
* This class models a HannoiTower.
*
* @author 程宇恒
* @version 1.0.0
*/
import javax.swing.*;
import java.awt.*;
public class Hanoi11 extends JPanel
implements Runnable
{
/*定义字体*/
static final Font titleFont = new Font("", 1, 12),
textFont = new Font("", 0, 11),
monoFont = new Font("", 1, 12);
static final int CANVAS_WIDTH = 450,
CANVAS_HEIGHT = 250,
TABLE_TOP = 225;
static final int PEG1 = 0, PEG2 = 1,PEG3 = 2, MIN_DISCS = 3, MAX_DISCS = 9;//游戏常量
protected boolean gameOver;//游戏结束
private int sourceDisc;
private int sourcePeg;
private int targetPeg;
private String gameStatus;//游戏状态
private JPanel cpBack;
private JPanel titlePanel;
private JLabel titleLabel;
protected Board bd;
private BoardCanvas bc;//游戏布局
private StatusPanel sp;//状态控制板
private ControlPanel cp;
private Image boardImage;
private String boardImageFile = "board.gif";//游戏背景图片
private Thread solveThread,timer;//游戏进程
private ImageIcon icon ;
public Hanoi11()
{
setBackground(Color.LIGHT_GRAY);
setLayout(new BorderLayout(0, 0));
/*BoardCanvas*/
bc = new BoardCanvas(this);
bc.setSize(25, 10);
titlePanel = new JPanel();
titlePanel.setLayout(new GridLayout(1, 1));
titlePanel.setBackground(Color.gray);
titlePanel.setFont(titleFont);
titlePanel.add(titleLabel = new JLabel(" 汉诺塔二代", 0));
titleLabel.setForeground(Color.black);
/*控制面板*/
cpBack = new JPanel();
cpBack.setBackground(Color.black);
cp = new ControlPanel(this);
cpBack.add(cp);
/*状态控制面板*/
sp = new StatusPanel(this);
sp.setBackground(Color.black);
icon = new ImageIcon("board.gif" ,
"an image with tower");
JLabel label = new JLabel(icon);
label.setVerticalTextPosition(JLabel.TOP);
label.setHorizontalTextPosition(JLabel.LEFT);
add(label);
add("Center", bc);
add("North", titlePanel);
add("East", cpBack);
add("South", sp);
MediaTracker mediatracker = new MediaTracker(this);
boardImage = icon.getImage();
mediatracker.addImage(boardImage, 0);
try
{
mediatracker.waitForID(0);
}
catch(InterruptedException interruptedexception) { }
}
/* public void init()//init重写
{
newGame();
}*/
/*开始游戏*/
void newGame()
{
int i = cp.getDiscs();
System.gc();
gameOver = false;
bd = new Board(i, this);
bc.drawBoard(bd, boardImage, 0, 0, 0);
sp.setMoveCount(0);
if(cp.isTimerOn())
timer = new Timer(cp);
else
cp.setTimer(" ");
if(solveThread == null)
sp.setStatus("移动所有的"+i+"个盘子到最右边的柱子");
bc.requestFocusInWindow();//This component must be displayable, visible, and focusable
}
/*重新开始游戏*/
void restartGame()
{
stop();
cp.setAutoSolveEnable(true);
newGame();
}
/*停止*/
public void stop()
{
if(solveThread != null)
{
solveThread.stop();
solveThread = null;
}
if(timer != null)
{
timer.stop();
timer = null;
}
}
public void startSolveThread()
{
stop();
solveThread = new Thread(this);
solveThread.start();
}
public void run()
{
newGame();
sp.setStatus("自动演示");
solve(cp.getDiscs(), 0, 1, 2);
sp.setStatus("完成!");
gameOver = true;
solveThread = null;
cp.setAutoSolveEnable(true);
}
/*实现汉诺塔自动移动的递归算法*/
void solve(int i, int j, int k, int l)
{
if(i == 0)
return;
solve(i - 1, j, l, k);
bd.moveDisc(j, l);
sp.setMoveCount(bd.getMoveCount());
bc.drawBoard(bd, boardImage, 0, 0, 0);
try
{
Thread _tmp = solveThread;
Thread.sleep(cp.getDelay());
}
catch(InterruptedException interruptedexception) { }
solve(i - 1, k, j, l);
}
/*控制鼠标移动*/
void dragDisc(int i, int j)//拖盘子
{
if(!gameOver && sourceDisc != 0)
bc.drawBoard(bd, boardImage, sourceDisc, i, j);
}
void selectDisc(int i, int j)//选盘子
{
if(!gameOver && solveThread == null)
{
if(timer != null && !timer.isAlive())
timer.start();
sourcePeg = pixelToPeg(i, j);
if(bd.isStartPeg(sourcePeg))
{
sourceDisc = bd.getTopDisc(sourcePeg);
bc.drawBoard(bd, boardImage, sourceDisc, i, j);
}
}
}
void dropDisc(int i, int j)//放盘子
{
if(!gameOver && sourceDisc != 0)
{
targetPeg = pixelToPeg(i, j);
if(bd.moveDisc(sourceDisc, sourcePeg, targetPeg))
{
gameStatus = bd.getBoardStatus();
sp.setMoveCount(bd.getMoveCount());
if(gameStatus == null)
{
sp.setStatus("最少的移动步数是 "+bd.getMinMoves()+"步");
} else
{
gameOver = true;
stop();
sp.setStatus(gameStatus);
}
}
bc.drawBoard(bd, boardImage, 0, 0, 0);
sourceDisc = 0;
}
}
int pixelToPeg(int i, int j)
{
int b = -1;
if(j > 40 && j < 225)
if(i > 50 && i < 100)
b = 0;
else
if(i > 200 && i < 250)
b = 1;
else
if(i > 350 && i < 400)
b = 2;
return b;
}
public static void main(String args[])
{
JFrame frame = new JFrame("汉诺塔二代");
frame.setContentPane(new Hanoi11());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack(); // Adjust the size of the window
frame.setVisible(true);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -