我也贴一个,哈哈,汉诺塔,大家不会不知道吧。
前阵子上数据结构讲到Hanoi,自己好玩就作了一个,
做的不怎么样吧,大家提提意见。
文件1: HanoiFrame.java
import java.awt.*; import java.io.*; import java.util.*; import java.awt.event.*; import javax.swing.*;
/** Frame with panel of Hanoi, buttons and menus. */ class HanoiFrame extends JFrame { /** Constructs the frame with HanoiPanel and buttons. */ public HanoiFrame() { setTitle(TITLE); setSize(WIDTH, HEIGHT); setLocation(X, Y); setResizable(false);
if(!FILE.exists()) { try { FILE.createNewFile(); PrintWriter out = new PrintWriter(new FileWriter(FILE), true);
for(int i = 0; i < NRECORD; i++) { records[i] = 999; names[i] = "匿名"; out.println(records[i] + "|" + names[i]); }
out.close();
} catch(IOException e) { JOptionPane.showConfirmDialog(this, "文件输入错误!", "错误", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE); } }
readRecords();
JMenuBar menuBar = new JMenuBar(); setJMenuBar(menuBar);
JMenu gameMenu = new JMenu("游戏"); JMenu helpMenu = new JMenu("帮助"); menuBar.add(gameMenu); menuBar.add(helpMenu);
JMenuItem startItem = new JMenuItem("开局"); startItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { restartGame(); } });
JMenuItem simpleItem = new JMenuItem("初级"); simpleItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { FILE = FILE_E; setDif(EASY_DIF); restartGame(); } });
JMenuItem normalItem = new JMenuItem("中级"); normalItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { FILE = FILE_N; setDif(NORMAL_DIF); restartGame(); } });
JMenuItem hardItem = new JMenuItem("高级"); hardItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { FILE = FILE_H; setDif(HARD_DIF); restartGame(); } });
JMenuItem topItem = new JMenuItem("英雄榜"); topItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { showTop(); } });
JMenuItem exitItem = new JMenuItem("退出"); exitItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { System.exit(0); } });
gameMenu.add(startItem); gameMenu.addSeparator(); gameMenu.add(simpleItem); gameMenu.add(normalItem); gameMenu.add(hardItem); gameMenu.addSeparator(); gameMenu.add(topItem); gameMenu.addSeparator(); gameMenu.add(exitItem);
JMenuItem howPlay = new JMenuItem("如何游戏"); howPlay.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { showHowToPlay(); } });
JMenuItem aboutItem = new JMenuItem("关于Hanoi..."); aboutItem.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { showAboutHanoi(); } });
helpMenu.add(howPlay); helpMenu.addSeparator(); helpMenu.add(aboutItem);
Container contentPane = getContentPane(); panel = new HanoiPanel(currentDif); panel.setBackground(Color.white); contentPane.add(panel, BorderLayout.CENTER);
JButton leftButton = new JButton("<---"); leftButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { moveLeft(); } });
JButton rightButton = new JButton("--->"); rightButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { moveRight(); } });
JButton changeFocusButton = new JButton("转换焦点"); changeFocusButton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent event) { focusChange(); } });
JPanel buttonPanel = new JPanel(); buttonPanel.add(leftButton); buttonPanel.add(rightButton); buttonPanel.add(changeFocusButton); contentPane.add(buttonPanel, BorderLayout.SOUTH);
counter = new JTextField(); counter.setEditable(false); counter.setText("0"); contentPane.add(counter, BorderLayout.NORTH); }
/** Restarts the game. */ public void restartGame() { //this.setVisible(false); this.dispose(); HanoiFrame frame = new HanoiFrame(); frame.setLocation(this.getX(), this.getY()); frame.show(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }
/** Sets the difference. @param dif the difference */ public void setDif(int dif) { currentDif = dif; }
/** Moves floor to left lines. */ public void moveLeft() { int to = focus-1 >= 0 ? focus-1 : 2; if(panel.access(focus,to)) { panel.moveF(focus, to); steps++; counter.setText(steps + ""); }
if(win()) { if(breakRecord()) recordTop(JOptionPane.showInputDialog("你好厉害哦,破了纪录了!\n 留下你的大名把:")); else JOptionPane.showConfirmDialog(this, "成功了!恭喜你!", "Finish", JOptionPane.DEFAULT_OPTION);
restartGame(); } }
/** Moves floor to right lines. */ public void moveRight() { int to = focus+1 <= 2 ? focus+1 : 0; if(panel.access(focus,to)) { panel.moveF(focus, to); steps++; counter.setText(steps + ""); }
if(win()) { if(breakRecord()) recordTop(JOptionPane.showInputDialog("你好厉害哦,破了纪录了!\n 留下你的大名把:")); else JOptionPane.showConfirmDialog(this, "成功了!恭喜你!", "Finish", JOptionPane.DEFAULT_OPTION);
restartGame(); } }
/** Changes the focus. */ public void focusChange() { focus = focus+1 <= 2 ? focus+1 : 0; panel.changeFocus(focus); }
/** Tests if the Hanoi is win. */ public boolean win() { return panel.isFinish(); }
/** Show how to play game. */ public void showHowToPlay() { JOptionPane.showConfirmDialog(this, HOW_PLAY_STR, "帮助", JOptionPane.DEFAULT_OPTION); }
/** Show message about this program. */ public void showAboutHanoi() { JOptionPane.showConfirmDialog(this, ABOUT_STR, "帮助", JOptionPane.DEFAULT_OPTION); }
/** Read the record to static Stirngs. */ public void readRecords() { try { BufferedReader in = new BufferedReader(new FileReader(FILE)); StringTokenizer z;
for(int i = 0; i < NRECORD; i++) { z = new StringTokenizer(in.readLine(), "|"); if(z.hasMoreTokens()) records[i] = Integer.parseInt(z.nextToken()); if(z.hasMoreTokens()) names[i] = z.nextToken(); }
in.close(); } catch(IOException e) { JOptionPane.showConfirmDialog(this, "无法读取指定文件!", "错误", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE); } }
/** Tests if the record is broken. @return if the record is broken return true */ public boolean breakRecord() { return steps < records[NRECORD-1]; }
/** Write the record to the file. @param name the name of the people who broken the record */ public void recordTop(String name) { for(int i = 0; i < NRECORD; i++) { if(steps < records[i]) { for(int j = NRECORD-1; j > i; j--) { records[j] = records[j-1]; names[j] = names[j-1]; } records[i] = steps; names[i] = name; break; } }
try { PrintWriter out = new PrintWriter(new FileWriter(FILE), true); for(int i = 0; i < NRECORD; i++) { out.println(records[i] + "|" + names[i]); }
out.close(); } catch(IOException e) { JOptionPane.showConfirmDialog(this, "无法写入指定文件!", "错误", JOptionPane.DEFAULT_OPTION, JOptionPane.ERROR_MESSAGE); } }
/** Shows the top records. */ public void showTop() { StringBuffer sb = new StringBuffer(); for(int i = 0; i < NRECORD; i++) sb.append((i+1) + " " + names[i] + ": " + records[i] + "\n"); JOptionPane.showConfirmDialog(this, sb.toString(), "英雄榜", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE); }
public static final String TITLE = "汉诺塔"; public static final int WIDTH = 600; public static final int HEIGHT = 400; public static final int X = 220; public static final int Y = 140;
public static final int EASY_DIF = 3; public static final int NORMAL_DIF = 4; public static final int HARD_DIF = 5; public static final int DEFAULT_DIF = NORMAL_DIF; private static int currentDif = DEFAULT_DIF;
private HanoiPanel panel; private int focus = 0; JTextField counter;
private static final File FILE_E = new File("topEasy.dat"); private static final File FILE_N = new File("topNormal.dat"); private static final File FILE_H = new File("topHard.dat"); private static File FILE = FILE_N;
private int steps = 0;
private int[] records = new int[NRECORD]; private String[] names = new String[NRECORD]; public static final int NRECORD = 5;
public static final String HOW_PLAY_STR = "这么有名的汉诺塔不会不会玩吧,\n如果真的不会玩问问你旁边的人吧,哈哈。"; public static final String ABOUT_STR = "汉诺塔 v1.0\n版权为 顾颖钧 所有:)";
public static void main(String[] args) { HanoiFrame frame = new HanoiFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.show(); } }
文件2: HanoiPanel.java
import java.awt.*; import java.awt.geom.*; import javax.swing.*; import java.util.*;
/** A panel that draws the Hanoi. */ class HanoiPanel extends JPanel { /** Constructs a panel draws the Hanoi that have n floors. @param n the number of floors */ public HanoiPanel(int n) { NFLOORS = n; floor = new Rectangle2D[NFLOORS]; for(int i = 0; i < LINE.length; i++) { line[i] = new Stack(); }
for(int i = 0; i < NFLOORS; i++) { double width = MIN_FLOOR_WIDTH + D_FW * i; double x = LINE0_X - width / 2; double y = LINE_Y + LINE_HEIGHT - FLOOR_HEIGHT * (NFLOORS - i); floor[i] = new Rectangle2D.Double(x, y, width, FLOOR_HEIGHT); }
for(int i = NFLOORS-1; i >= 0; i--) { line[0].push(floor[i]); }
LINE[0] = new Rectangle2D.Double(LINE0_X, LINE_Y, LINE_WIDTH, LINE_HEIGHT); LINE[1] = new Rectangle2D.Double(LINE0_X + D_LX, LINE_Y, LINE_WIDTH, LINE_HEIGHT); LINE[2] = new Rectangle2D.Double(LINE0_X + D_LX * 2, LINE_Y, LINE_WIDTH, LINE_HEIGHT); }
public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D)g;
for(int i = 0; i < LINE.length; i++) { g2.setColor(Color.yellow); if(i == focusLine) g2.setColor(Color.green); g2.fill(LINE[i]); }
g2.setColor(Color.black); for(int i = 0; i < NFLOORS; i++) { g2.fill(floor[i]); } }
/** Moves one floor from the top of one line to another. @param from the line that moves from @param to the line that the floor moves to, the first line is 0 @return the record of moving */ public String moveF(int from, int to) { if(line[from].isEmpty() || !access(from, to)) return ""; changeFocus(from);
Rectangle2D moveFloor = (Rectangle2D)(line[from].pop()); int toLineLen = line[to].size(); double x = LINE[to].getX() - moveFloor.getWidth() / 2; double y = LINE_Y + LINE_HEIGHT - FLOOR_HEIGHT * (toLineLen + 1);
moveFloor.setFrame(x, y, moveFloor.getWidth(), moveFloor.getHeight()); line[to].push(moveFloor); repaint();
return "From " + (from+1) + " to " + (to+1) + " "; }
/** Tests if the moving is access. @param from the floor moves from @param to the line that the floor moves to, the first line is 0 @return if the wider floor is move up to the shorter one return false */ public boolean access(int from, int to) { if(line[from].isEmpty()) return false; if(line[to].isEmpty()) return true;
Rectangle2D upRect = (Rectangle2D)(line[from].peek()); Rectangle2D downRect = (Rectangle2D)(line[to].peek());
if(upRect.getWidth() > downRect.getWidth()) return false; return true; }
/** Change the focus of line. @param line the focus */ public void changeFocus(int line) { focusLine = line; repaint(); }
/** Tests if the Hanoi is finish. */ public boolean isFinish() { return line[2].size() == NFLOORS; }
private Rectangle2D[] floor; private static Rectangle2D[] LINE = new Rectangle2D[3]; private Stack[] line = new Stack[3]; private int focusLine = 0;
private int NFLOORS;
public static final double MIN_FLOOR_WIDTH = 25; public static final double D_FW = 35; public static final double FLOOR_HEIGHT = 30;
public static final double LINE_WIDTH = 2; public static final double LINE_HEIGHT = 200; public static final double LINE_Y = 80; public static final double LINE0_X = 120; public static final double D_LX = 180;
public static void main(String[] args) { HanoiPanel panel = new HanoiPanel(5); JFrame frame = new JFrame(); frame.setSize(600,400); frame.setTitle("Hanoi"); Container contentPane = frame.getContentPane(); contentPane.add(panel); frame.show();
StringBuffer strBuf = new StringBuffer(); JOptionPane.showConfirmDialog(panel, "Go next step.", "Confirm", JOptionPane.DEFAULT_OPTION); strBuf.append(panel.moveF(0,2) + ",");JOptionPane.showConfirmDialog(panel, "Go next step.", "Confirm", JOptionPane.DEFAULT_OPTION); strBuf.append(panel.moveF(0,1) + ",");JOptionPane.showConfirmDialog(panel, "Go next step.", "Confirm", JOptionPane.DEFAULT_OPTION); strBuf.append(panel.moveF(2,1) + ",");JOptionPane.showConfirmDialog(panel, "Go next step.", "Confirm", JOptionPane.DEFAULT_OPTION); strBuf.append(panel.moveF(0,2) + ",");JOptionPane.showConfirmDialog(panel, "Go next step.", "Confirm", JOptionPane.DEFAULT_OPTION); strBuf.append(panel.moveF(1,0) + ",");JOptionPane.showConfirmDialog(panel, "Go next step.", "Confirm", JOptionPane.DEFAULT_OPTION); strBuf.append(panel.moveF(1,2) + ",");JOptionPane.showConfirmDialog(panel, "Go next step.", "Confirm", JOptionPane.DEFAULT_OPTION); strBuf.append(panel.moveF(0,2) + "."); if(panel.isFinish()) JOptionPane.showConfirmDialog(panel, "Congraturation!", "Finish", JOptionPane.DEFAULT_OPTION); System.exit(0); } }