数据结构课程设计扫雷游戏实验报告及JAVA源代码.docx
- 文档编号:10293020
- 上传时间:2023-05-24
- 格式:DOCX
- 页数:60
- 大小:489.70KB
数据结构课程设计扫雷游戏实验报告及JAVA源代码.docx
《数据结构课程设计扫雷游戏实验报告及JAVA源代码.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计扫雷游戏实验报告及JAVA源代码.docx(60页珍藏版)》请在冰点文库上搜索。
数据结构课程设计扫雷游戏实验报告及JAVA源代码
数据结构课程设计报告
扫雷游戏
学院:
班级:
姓名:
学号:
日期:
一系统开发平台
题目:
扫雷游戏
开发语言:
JAVA
开发工具:
Eclipse
操作系统:
MicrosoftWindows7
二设计要求
二.1问题描述
实现一个M*N的扫雷游戏。
2.2输入要求
2.1.1左键单击:
在判断出不是雷的方块上按下左键,可以打开该方块。
如果方块上出现数字,则该数字表示其周围3×3区域中的地雷数(一般为8个格子,对于边块为5个格子,对于角块为3个格子。
所以扫雷中最大的数字为8);如果方块上为空(相当于0),则可以递归地打开与空相邻的方块;如果不幸触雷,则游戏结束。
2.1.2右键单击:
在判断为地雷的方块上按下右键,可以标记地雷(显示为小红旗)。
重复两次操作可取消标记。
2.1.3双击:
同时按下左键和右键完成双击。
当双击位置周围已标记雷数等于该位置数字时操作有效,相当于对该数字周围未打开的方块均进行一次左键单击操作。
地雷未标记完全时使用双击无效。
若数字周围有标错的地雷,则游戏结束。
一
二
二.1
二.2
二.3输出要求
以图形界面的形式输出游戏数据,如下图:
三数据结构与算法描述
三.1整体思路
三
三.1
三.2所需数据结构及算法
一
二
三
三.1
三.2
三.2.1数据结构
记录类区的各个属性用到了二维数组
三.2.2算法
点击到空白格子时递归的打开周围的八个格子用到了递归算法:
四测试结果
四.1测试输入及输出
四.1.1初级游戏
四
四.1
四.1.1
四.1.2中级游戏
一
二
三
四
四.1
四.1.1
四.1.2
四.1.3高级游戏
一
二
三
四
四.1
四.1.1
四.1.2
四.1.3
四.1.4自定义游戏对话框
一
二
三
四
四.1
四.1.1
四.1.2
四.1.3
四.1.4
四.1.5自定义游戏及游戏结束
一
二
三
四
四.1
四.1.1
四.1.2
四.1.3
四.1.4
四.1.5
四.1.6游戏胜利
四.1.7帮助
四.1.8关于
四.2测试中的问题及解决
问题1:
测试过程中,发现地雷实际显示的位置和它应该显示的位置不同,正好沿着左上右下斜对角线对称;
解决:
由于坐标(i,j)表示i行j列,i对应到屏幕上坐标为Y轴,j对应到屏幕上坐标为X轴,所以造成了地雷实际显示的位置和它应该显示的位置不同,发现这个问题后,将paint中的i,j对调一下便得到了正确结果。
问题2:
由于线程中的stop()方法已不建议使用,为了终止计时器线程,我设定了一个标记booleanflag,用来控制线程的结束,flag=true时,计时器线程不断+1,flag=false时,计时器线程终止。
测试过程中,发现游戏开始后点击开始按钮,计时器总会显示为1而不是0;
解决:
由于对线程理解不足,产生生这个问题的原因目前还不清楚,不过经过上网查询后得到了解决办法。
由于计时器线程运行时使用了sleep方法,线程处于阻塞状态,因此利用interrupt方法来中断线程,解决了这个问题。
五分析与讨论
五.1测试结果分析
由于题目的特殊性,没有测试数据,具体的测试结果参见4.1测试输入及输出。
分析:
多次测试结果显示程序运行正常,无异常。
一
二
三
四
五
五.1
五.1.1
五.2算法复杂性分析
由于点击到空白格子时递归的打开周围的八个格子用到了递归算法;
算法复杂性:
检查1层格子最多检查9个格子;
检查2层格子最多检查25个格子;
检查3层格子最多检查49个格子;
检查4层格子最多检查81个格子;
检查5层格子最多检查121个格子;
……;
检查N层格子最多检查(2N+1)²个格子;
实际算法复杂性:
O(N²)
五.3探讨及改进
五.3.1主要算法采用了递归的方法,虽清晰易懂,但效率不高,可以改为非递归的采用队列实现的算法,这样算法的效率有明显的提高。
五.3.2扫雷区域内显示的数字是即时画上去的,可以采用图片填充的方法,这样子界面更加美观,且容易更改界面外观。
六附录(源代码)
六.1classStart
packagesaolei;
/**
*@authorJSM开始游戏
*/
publicclassStart
{
publicstaticvoidmain(String[]args)
{
newWindow();
}
}
一
二
三
四
五
六
六.1
六.2classWindow
packagesaolei;
importjavax.swing.*;
importjava.awt.*;
importjava.awt.event.*;
/**
*@authorJSM游戏窗口,继承自JFrame
*/
publicclassWindowextendsJFrame
{
/**
*
*/
privatestaticfinallongserialVersionUID=819044217250493847L;
//获取屏幕尺寸
DimensionscreenSize=Toolkit.getDefaultToolkit().getScreenSize();
//设定屏幕大小位置的参数
intwidth;
intheight;
intx;
inty;
//菜单栏
JMenuBarmenu=newJMenuBar();
//菜单条目
JMenugame=newJMenu("游戏");
JMenuItemstart=newJMenuItem("开局");
JMenuItemprimary=newJMenuItem("初级");
JMenuItemintermediate=newJMenuItem("中级");
JMenuItemsenior=newJMenuItem("高级");
JMenuItemcustom=newJMenuItem("自定义");
//JMenuItemmark=newJMenuItem("标记(?
)");
//JMenuItemstyle=newJMenuItem("风格");
//JMenuItemrank=newJMenuItem("扫雷英雄榜");
JMenuItemquit=newJMenuItem("退出");
JMenuhelp=newJMenu("帮助");
JMenuItemabout=newJMenuItem("关于");
//游戏界面
Playp;
/*
*空构造器
*/
publicWindow()
{
this(9,9,10);
}
/*
*构造器,传入扫雷界面的行数M,列数N,雷数SUM
*/
publicWindow(finalintM,finalintN,finalintSUM)
{
//调用父类构造器,设定窗口标题
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(newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
setVisible(false);
newWindow(M,N,SUM);
}
});
game.add(start);
game.addSeparator();
//初级按钮添加监听器
primary.addActionListener(newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
setVisible(false);
newWindow(9,9,10);
}
});
game.add(primary);
//中级按钮添加监听器
intermediate.addActionListener(newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
setVisible(false);
newWindow(16,16,40);
}
});
game.add(intermediate);
//高级按钮添加监听器
senior.addActionListener(newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
setVisible(false);
newWindow(16,30,99);
}
});
game.add(senior);
//自定义按钮添加监听器
custom.addActionListener(newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
newWin();
}
});
game.add(custom);
//game.addSeparator();
//game.add(mark);
//game.add(style);
//game.addSeparator();
//game.add(rank);
game.addSeparator();
//退出按钮添加监听器,结束程序
quit.addActionListener(newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
System.exit(0);
}
});
game.add(quit);
menu.add(game);
//添加菜单栏的帮助
about.addActionListener(newActionListener()
{
publicvoidactionPerformed(ActionEvente)
{
//for(inti=0;i<10;i++)
newMyDialog();
}
});
help.add(about);
menu.add(help);
//为窗口添加菜单栏
setJMenuBar(menu);
//初始化扫雷区域并添加到窗口
p=newPlay(M,N,SUM);
add(p);
//设置为不可改变大小
setResizable(false);
setVisible(true);
}
publicvoidnewWin()
{
newMyDialog(this);
}
//游戏面板
}
六.3classPlay
packagesaolei;
importjava.awt.BorderLayout;
importjava.awt.Color;
importjava.awt.Font;
importjava.awt.Graphics;
importjava.awt.GridLayout;
importjava.awt.Image;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjava.awt.event.MouseAdapter;
importjava.awt.event.MouseEvent;
importjava.io.File;
importjava.io.IOException;
importjava.util.Random;
importjavax.imageio.ImageIO;
importjavax.swing.ImageIcon;
importjavax.swing.JButton;
importjavax.swing.JLabel;
importjavax.swing.JPanel;
/**
*@authorJSM游戏主界面
*/
publicclassPlayextendsJPanel
{
/**
*
*/
privatestaticfinallongserialVersionUID=-3580495857255725500L;
//每个小格子边长
finalstaticintSPACE=25;
//界面大小,相对于窗口的坐标
intheight;
intwidth;
intxy=2*SPACE;
//m行n列sum个地雷的扫雷游戏
intm,n,sum;
//定义三个图标
ImageimgMine;
ImageimgMineX;
ImageimgFlag;
ImageimgMark;
//记录扫雷状态的二维数组
Lattice[][]mine;
//开始按钮
JButtonface=newJButton("开始");
//地雷计数器,初始值为地雷数目
intcount;
JCountercounter;
//计时器及线程
JCountertime;
TimeCounterThreadtimer;
//记录游戏是否开始,初始值为false
booleanisStart=false;
//构造方法,传入扫雷界面的行数m,列数n,雷数sum
publicPlay(intm,intn,intsum)
{
//设置界面大小
height=m*SPACE;
width=n*SPACE;
//传入界面行数,列数及地雷数
this.m=m;
this.n=n;
this.sum=sum;
//读取三个图标
try
{
imgMine=ImageIO.read(newFile("地雷.jpg"));
imgMineX=ImageIO.read(newFile("地雷x.jpg"));
imgFlag=ImageIO.read(newFile("小旗.jpg"));
imgMark=ImageIO.read(newFile("问号.jpg"));
}
catch(IOExceptione)
{
e.printStackTrace();
}
//初始化地雷计数器
count=sum;
counter=newJCounter(count);
//初始化计时器线程
time=newJCounter();
timer=newTimeCounterThread(time);
//设定给定行数和给定列数的记录扫雷信息的二维数组的大小
mine=newLattice[this.m][this.n];
//初始化二维数组
for(inti=0;i { for(intj=0;j { //System.out.print(i+""); //System.out.println(mine[i][j].getLat()); mine[i][j]=newLattice(); } } //设置大小 setSize(width,height); //添加鼠标监听器 addMouseListener(newPMouseListener()); //设置布局 setLayout(newBorderLayout(5,10)); //放置界面上方的三个组件 JPanelp=newJPanel(); //设置布局 p.setLayout(newGridLayout(1,0)); JPanelp1=newJPanel(); p1.add(newJLabel(newImageIcon("地雷1.jpg"))); p1.add(counter); JPanelp2=newJPanel(); //开始按钮添加监听器,开始一个新的游戏 face.addActionListener(newActionListener() { publicvoidactionPerformed(ActionEvente) { //游戏未开始 isStart=false; //计时器线程结束 timer.flag=false; //timer.stop(); timer.interrupt(); //重置游戏界面 reset(); } }); p2.add(face); JPanelp3=newJPanel(); p3.add(newJLabel(newImageIcon("时钟.png"))); p3.add(time); p.add(p1); p.add(p2); p.add(p3); add(p,BorderLayout.NORTH); } //构造器 publicPlay() { this(9,9,10); } //重置游戏界面 publicvoidreset() { //初始化地雷计数器 count=sum; counter.resetCounter(count); //计时器所显示数字重置为0 time.resetCounter(0); timer=newTimeCounterThread(time); //System.out.println(555); //System.out.print(time.getCounterNum()); //初始化二维数组 for(inti=0;i { for(intj=0;j { //System.out.print(i+""); //System.out.println(mine[i][j].getLat()); mine[i][j].setLat(0); mine[i][j].setMark(0); mine[i][j].setOpen(false); } } //重画游戏界面 repaint(); } //publicvoidreset(inta,intb,intc) //{ //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=newTimeCounterThread(time); ////初始化二维数组
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 扫雷 游戏 实验 报告 JAVA 源代码