数据结构课程设计扫雷游戏实验报告及JAVA源代码.doc_第1页
数据结构课程设计扫雷游戏实验报告及JAVA源代码.doc_第2页
数据结构课程设计扫雷游戏实验报告及JAVA源代码.doc_第3页
数据结构课程设计扫雷游戏实验报告及JAVA源代码.doc_第4页
数据结构课程设计扫雷游戏实验报告及JAVA源代码.doc_第5页
已阅读5页,还剩50页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

数据结构课程设计数据结构课程设计报告扫雷游戏学院: 班级:姓名: 学号:日期:目录一系统开发平台3二设计要求32.1问题描述32.2输入要求32.3输出要求4三数据结构与算法描述43.1整体思路43.2所需数据结构及算法5四测试结果64.1测试输入及输出64.2测试中的问题及解决12五分析与讨论125.1测试结果分析125.2算法复杂性分析135.3探讨及改进13六附录(源代码)146.1class Start146.2class Window146.3class Play206.4class Lattice406.5class JCounter426.6class TimeCounterThread466.7class MyDialog47一 系统开发平台题目:扫雷游戏开发语言:JAVA开发工具:Eclipse操作系统:Microsoft Windows 7二 设计要求2.1 问题描述实现一个M*N的扫雷游戏。2.2 输入要求2.1.1 左键单击:在判断出不是雷的方块上按下左键,可以打开该方块。如果方块上出现数字,则该数字表示其周 围33区域中的地雷数(一般为8个格子,对于边块为5个格子,对于角块为3个格子。所以扫雷中最大的数字为8);如果方块上为空(相当于0),则可以递 归地打开与空相邻的方块;如果不幸触雷,则游戏结束。2.1.2 右键单击:在判断为地雷的方块上按下右键,可以标记地雷(显示为小红旗)。重复两次操作可取消标记。2.1.3 双击:同时按下左键和右键完成双击。当双击位置周围已标记雷数等于该位置数字时操作有效,相当于对该数字周围未打开的方块均进行一次左键单击操作。地雷未标记完全时使用双击无效。若数字周围有标错的地雷,则游戏结束。一 二 2.1 2.2 2.3 输出要求以图形界面的形式输出游戏数据,如下图:三 数据结构与算法描述3.1 整体思路三 3.1 3.2 所需数据结构及算法一 二 三 3.1 3.2 3.2.1 数据结构记录类区的各个属性用到了二维数组3.2.2 算法点击到空白格子时递归的打开周围的八个格子用到了递归算法:四 测试结果4.1 测试输入及输出4.1.1 初级游戏四 4.1 4.1.1 4.1.2 中级游戏一 二 三 四 4.1 4.1.1 4.1.2 4.1.3 高级游戏一 二 三 四 4.1 4.1.1 4.1.2 4.1.3 4.1.4 自定义游戏对话框一 二 三 四 4.1 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 自定义游戏及游戏结束一 二 三 四 4.1 4.1.1 4.1.2 4.1.3 4.1.4 4.1.5 4.1.6 游戏胜利4.1.7 帮助4.1.8 关于 4.2 测试中的问题及解决问题1:测试过程中,发现地雷实际显示的位置和它应该显示的位置不同,正好沿着左上右下斜对角线对称;解决:由于坐标(i,j)表示i行j列,i对应到屏幕上坐标为Y轴,j对应到屏幕上坐标为X轴,所以造成了地雷实际显示的位置和它应该显示的位置不同,发现这个问题后,将paint中的i,j对调一下便得到了正确结果。问题2:由于线程中的stop()方法已不建议使用,为了终止计时器线程,我设定了一个标记boolean flag,用来控制线程的结束,flag=true时,计时器线程不断+1,flag=false时,计时器线程终止。测试过程中,发现游戏开始后点击开始按钮,计时器总会显示为1而不是0;解决:由于对线程理解不足,产生生这个问题的原因目前还不清楚,不过经过上网查询后得到了解决办法。由于计时器线程运行时使用了sleep方法,线程处于阻塞状态,因此利用interrupt方法来中断线程,解决了这个问题。五 分析与讨论5.1 测试结果分析由于题目的特殊性,没有测试数据,具体的测试结果参见4.1 测试输入及输出。分析:多次测试结果显示程序运行正常,无异常。一 二 三 四 五 5.1 5.1.1 5.2 算法复杂性分析由于点击到空白格子时递归的打开周围的八个格子用到了递归算法;算法复杂性:检查1层格子最多检查9个格子;检查2层格子最多检查25个格子;检查3层格子最多检查49个格子;检查4层格子最多检查81个格子;检查5层格子最多检查121个格子;检查N层格子最多检查(2N+1)个格子;实际算法复杂性:O(N)5.3 探讨及改进5.3.1 主要算法采用了递归的方法,虽清晰易懂,但效率不高,可以改为非递归的采用队列实现的算法,这样算法的效率有明显的提高。5.3.2 扫雷区域内显示的数字是即时画上去的,可以采用图片填充的方法,这样子界面更加美观,且容易更改界面外观。六 附录(源代码)6.1 class Startpackage saolei;/* * author JSM 开始游戏 */public class Startpublic static void main(String args)new Window();一 二 三 四 五 六 6.1 6.2 class Windowpackage saolei;import javax.swing.*;import java.awt.*;import java.awt.event.*;/* * author JSM 游戏窗口,继承自 JFrame */public class Window extends JFrame/* * */private static final long serialVersionUID = 819044217250493847L;/ 获取屏幕尺寸Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();/ 设定屏幕大小位置的参数int width;int height;int x;int y;/ 菜单栏JMenuBar menu = new JMenuBar();/ 菜单条目JMenu game = new JMenu(游戏);JMenuItem start = new JMenuItem(开局);JMenuItem primary = new JMenuItem(初级);JMenuItem intermediate = new JMenuItem(中级);JMenuItem senior = new JMenuItem(高级);JMenuItem custom = new JMenuItem(自定义);/ JMenuItem mark = new JMenuItem(标记(?);/ JMenuItem style = new JMenuItem(风格);/ JMenuItem rank = new JMenuItem(扫雷英雄榜);JMenuItem quit = new JMenuItem(退出);JMenu help = new JMenu(帮助);JMenuItem about = new JMenuItem(关于);/ 游戏界面Play p;/* * 空构造器 */public Window()this(9, 9, 10);/* * 构造器,传入扫雷界面的行数M,列数N,雷数SUM */public Window(final int M, final int N, final int SUM)/ 调用父类构造器,设定窗口标题super(扫雷);/ 窗口的宽度和高度,经过精密测量得到的结果width = (N + 4) * Play.SPACE + 17;height = (M + 6) * Play.SPACE + 14;/ 窗口的位置,放在屏幕中央x = (screenSize.width - width) / 2;y = (screenSize.height - height) / 2;/ 设置大小,位置setBounds(x, y, width, height);setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);/ 开局按钮添加监听器start.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)setVisible(false);new Window(M, N, SUM););game.add(start);game.addSeparator();/ 初级按钮添加监听器primary.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)setVisible(false);new Window(9, 9, 10););game.add(primary);/ 中级按钮添加监听器intermediate.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)setVisible(false);new Window(16, 16, 40););game.add(intermediate);/ 高级按钮添加监听器senior.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)setVisible(false);new Window(16, 30, 99););game.add(senior);/ 自定义按钮添加监听器custom.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)newWin(););game.add(custom);/ game.addSeparator();/ game.add(mark);/ game.add(style);/ game.addSeparator();/ game.add(rank);game.addSeparator();/ 退出按钮添加监听器,结束程序quit.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)System.exit(0););game.add(quit);menu.add(game);/ 添加菜单栏的帮助about.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)/ for (int i = 0; i 10; i+)new MyDialog(););help.add(about);menu.add(help);/ 为窗口添加菜单栏setJMenuBar(menu);/ 初始化扫雷区域并添加到窗口p = new Play(M, N, SUM);add(p);/ 设置为不可改变大小setResizable(false);setVisible(true);public void newWin()new MyDialog(this);/ 游戏面板6.3 class Playpackage saolei;import java.awt.BorderLayout;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.GridLayout;import java.awt.Image;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.io.File;import java.io.IOException;import java.util.Random;import javax.imageio.ImageIO;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JLabel;import javax.swing.JPanel;/* * author JSM 游戏主界面 */public class Play extends JPanel/* * */private static final long serialVersionUID = -3580495857255725500L;/ 每个小格子边长final static int SPACE = 25;/ 界面大小,相对于窗口的坐标int height;int width;int xy = 2 * SPACE;/ m行n列sum个地雷的扫雷游戏int m, n, sum;/ 定义三个图标Image imgMine;Image imgMineX;Image imgFlag;Image imgMark;/ 记录扫雷状态的二维数组Lattice mine;/ 开始按钮JButton face = new JButton(开始);/ 地雷计数器,初始值为地雷数目int count;JCounter counter;/ 计时器及线程JCounter time;TimeCounterThread timer;/ 记录游戏是否开始,初始值为falseboolean isStart = false;/ 构造方法,传入扫雷界面的行数m,列数n,雷数sumpublic Play(int m, int n, int sum)/ 设置界面大小height = m * SPACE;width = n * SPACE;/ 传入界面行数,列数及地雷数this.m = m;this.n = n;this.sum = sum;/ 读取三个图标tryimgMine = ImageIO.read(new File(地雷.jpg);imgMineX = ImageIO.read(new File(地雷x.jpg);imgFlag = ImageIO.read(new File(小旗.jpg);imgMark = ImageIO.read(new File(问号.jpg);catch (IOException e)e.printStackTrace();/ 初始化地雷计数器count = sum;counter = new JCounter(count);/ 初始化计时器线程time = new JCounter();timer = new TimeCounterThread(time);/ 设定给定行数和给定列数的记录扫雷信息的二维数组的大小mine = new Latticethis.mthis.n;/ 初始化二维数组for (int i = 0; i m; i+)for (int j = 0; j n; j+)/ System.out.print(i+);/ System.out.println(mineij.getLat();mineij = new Lattice();/ 设置大小setSize(width, height);/ 添加鼠标监听器addMouseListener(new PMouseListener();/ 设置布局setLayout(new BorderLayout(5, 10);/ 放置界面上方的三个组件JPanel p = new JPanel();/ 设置布局p.setLayout(new GridLayout(1, 0);JPanel p1 = new JPanel();p1.add(new JLabel(new ImageIcon(地雷1.jpg);p1.add(counter);JPanel p2 = new JPanel();/ 开始按钮添加监听器,开始一个新的游戏face.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e)/ 游戏未开始isStart = false;/ 计时器线程结束timer.flag = false;/ timer.stop();errupt();/ 重置游戏界面reset(););p2.add(face);JPanel p3 = new JPanel();p3.add(new JLabel(new ImageIcon(时钟.png);p3.add(time);p.add(p1);p.add(p2);p.add(p3);add(p, BorderLayout.NORTH);/ 构造器public Play()this(9, 9, 10);/ 重置游戏界面public void reset()/ 初始化地雷计数器count = sum;counter.resetCounter(count);/ 计时器所显示数字重置为0time.resetCounter(0);timer = new TimeCounterThread(time);/ System.out.println(555);/ System.out.print(time.getCounterNum();/ 初始化二维数组for (int i = 0; i m; i+)for (int j = 0; j n; j+)/ System.out.print(i+);/ System.out.println(mineij.getLat();mineij.setLat(0);mineij.setMark(0);mineij.setOpen(false);/ 重画游戏界面repaint();/ public void reset(int a, int b, int c)/ / m = a;/ n = b;/ sum = c;/ height = m * SPACE;/ width = n * SPACE;/ / 设置大小/ setSize(width, height);/ / 初始化地雷计数器/ count = sum;/ time.resetCounter(0);/ / System.out.print(time.getCounterNum();/ timer = new TimeCounterThread(time);/ / 初始化二维数组/ for (int i = m; i a; i+)/ / for (int j = n; j b; j+)/ / / System.out.print(i+);/ / System.out.println(mineij.getLat();/ mineij.setLat(0);/ mineij.setMark(0);/ mineij.setOpen(false);/ / / / 重写paint方法,绘制扫雷界面public void paint(Graphics g)super.paint(g);/ 良好的编程习惯Color c = g.getColor();/ 绘制界面上的小格子g.setColor(new Color(16, 234, 245);for (int i = 0; i n; i+)for (int j = 0; j m; j+)g.fill3DRect(xy + SPACE * i + 1, xy + SPACE * j + 1, SPACE - 1,SPACE - 1, true);/ 绘制格子边框g.setColor(Color.BLACK);for (int i = 0; i m + 1; i+)g.drawLine(xy, xy + i * SPACE, xy + width, xy + i * SPACE);for (int i = 0; i n + 1; i+)g.drawLine(xy + i * SPACE, xy, xy + i * SPACE, xy + height);/ 绘制格子,包括空白,数字,地雷,小旗,问号for (int i = 0; i m; i+)for (int j = 0; j 0; k-)/ 先判断随机产生的位置是否已经是地雷,如果已经是地雷则此次操作回退i = r.nextInt(m);j = r.nextInt(n);/ System.out.print(ii + );/ System.out.println(jj+a);if (mineij.getLat() = 0 & i != a & j != b)mineij.setLat(9);elsek+;/ 下面进行判断,思路:遍历“地雷”位置,找到后对其附近的数组进行加1操作for (i = 0; i m; i+)for (j = 0; j 8)if (j 0)/ 保证列不越界mineij - 1.addLat();if (j 0)/ 上一行minei - 1j.addLat();if (j 0)minei - 1j - 1.addLat();if (j minei.length - 1)minei - 1j + 1.addLat();if (i 0)minei + 1j - 1.addLat();if (j minei.length - 1)minei + 1j + 1.addLat();/ 计时器开始计时timer.start();/ 重画界面repaint();/ 如果赢了,计时器线程结束,弹出对话框private void win()timer.flag = false;/ System.out.println(win);new MyDialog(m, n, sum, this, 恭喜!您赢了!);/ 如果输了,计时器线程结束,打开所有格子,弹出对话框private void bomb(int row, int col)timer.flag = false;/ System.out.println(Bomb!);/ timerThread.stop();for (int i = 0; i m; i+)for (int j = 0; j 8 | !mineij.isRight()if (mineij.getMark() != 1 | !mineij.isRight()mineij.setOpen(true);repaint();new MyDialog(m, n, sum, this, 不好意思,您输了。下次走运!);/ 判断赢private boolean isWin()/ 记录当前点开的格子的数目int over = 0;/ 遍历并记录当前点开的格子的数目for (int i = 0; i m; i+)for (int j = 0; j n; j+)if (mineij.getLat() 8)return true;elsereturn false;/ 检查给定坐标格子void checkMine(int row, int col)int i, j;i = row;j = col;/ System.out.println(i+ + (j);/ System.out.println(mineij.getLat();/ 如果此处没有被标记为小旗子或者问号if (mineij.getMark() != 1)/ 如果是地雷 则游戏结束if (isBomb(i, j)bomb(i, j);else/ 如果此处是0,则递归检查周围八个格子if (mineij.getLat() = 0 & !mineij.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论