武汉理工大学数据结构综合实验——连连看游戏综合实践
文章目录
- 实验目的
- 主要仪器设备及耗材
- 一、实验要求
- 二、分析与设计(非线性结构)
- 1.数据结构的设计
- 2.核心算法设计
- 一条直线消子
- 两条直线消子
- 三条直线消子
- 初始化游戏地图
- 搜寻路径
- 提示和重排
- 3.测试用例设计
- 4.测试效果
- 总结
实验目的
(1)线性结构实验目的
调研连连看游戏,了解连连看游戏的功能和规则等
掌握集成开发工具VS2019的使用和C++的基础编程
了解MFC框架
了解线性结构,掌握数组的遍历、消子和胜负判断等算法
了解企业软件开发过程,应用迭代开发思路进行项目开发,养成良好的编程习惯和培养软件工程化思维
(2)非线性结构实验目的
调研连连看游戏,了解连连看游戏的功能和规则等 掌握集成开发工具VS2019的使用和C++的基础编程
了解MFC框架
掌握图的数据结构和应用,图的常用算法,能够利用图的算法实现游戏连通判断和胜负判断
了解企业软件开发过程,应用迭代开发思路进行项目开发,养成良好的编程习惯和培养软件工程化思维
主要仪器设备及耗材
1.安装了Windows 10操作系统的PC机1台
2.PC机系统上安装了Microsoft Visual Studio 2019开发环境
以下是本篇文章正文内容,下面案例可供参考
一、实验要求
(1)线性结构实验要求
连连看游戏是对一堆图案中的相同图案进行配对的简单游戏,在一定的规则之内对相同的图案进行消除处理,在规定时间内消除所有图案后玩家就获胜。
主界面,进行各项操作的入口;
开始游戏,系统根据设置的主题风格生成一个图片布局,以供玩家点击消除
消子,对玩家选中的两种图片进行判断,判断是否符合消除规则;
判断胜负,当游戏完成后,需要判断游戏胜负;
提示,显示界面上能够消除的一对图片;
重排,根据随机数,重新排列游戏地图上的图片;
计时,设定一定时间来辅助游戏是否结束;
游戏模式,有基本模式、休闲模式和关卡模式三种,可以根据是否定时等规则进行设置,增强趣味性。
(2)非线性结构实验要求
与线性结构中的功能完全相同,不同点在于游戏数据存储结构和算法。
二、分析与设计(非线性结构)
依据上述的实验目的与要求,可导出实现的连连看游戏的流程为:
① 主界面设计(主界面布局,背景图片绘制)
② 开始游戏(添加游戏对话框,绘制游戏界面背景,游戏界面布局,加载游戏元素图片,绘制游戏地图)
③ 消子判断(添加鼠标事件,选择图片,消除相同元素图片,一条直线消子,两条直线消子,三条直线消子)
④ 判断胜负(判断胜负,控制开始游戏按钮状态)
⑤ 扩展功能(提示,重排)
1.数据结构的设计
代码如下(示例):
//保存游戏地图中的点
typedef struct tagVertex
{int row; //行int col; //列int info; //信息类
}Vertex;图存储结构
AdjMatrix m_AdjMatrix; //边数组 Vertices m_Vertices;//顶点数组int m_nVexnum; //顶点数int m_nArcnum; //边数量
2.核心算法设计
一条直线消子
代码如下(示例):
//连通判断
bool CGameLogic::IsLink(int anMap[][4], Vertex v1, Vertex v2) {//一条直线消子int nRow1 = v1.row;int nCol1 = v1.col;int nRow2 = v2.row;int nCol2 = v2.col;//把第一个点保存到数组AddVertex(v1);//判断能否横向连通if (nRow1 == nRow2){if (LinkInRow(anMap, v1, v2)){AddVertex(v2); //把第二个点保存到数组return true;}}//判断能否纵向连通if (nCol1 == nCol2){if (LinkInCol(anMap, v1, v2) == true){AddVertex(v2); //把第二个点保存到数组return true;}}//两条直线消子if (OneCornerLink(anMap, v1, v2) == true){AddVertex(v2);return true;}//三条直线消子if (TwoCornerLink(anMap, v1, v2) == true){AddVertex(v2);return true;}DeleteVertex();return false;
}//行号相同时,判断横向是否连通
bool CGameLogic::LinkInRow(int anMap[][4], Vertex v1, Vertex v2) {int nCol1 = v1.col;int nCol2 = v2.col;int nRow = v1.row;//保证nCol1的值小于nCol2if (nCol1 > nCol2) {//数据交换int nTemp = nCol1;nCol1 = nCol2;nCol2 = nTemp;}//直通for (int i = nCol1 + 1; i <= nCol2; i++){if (i == nCol2)return true;if (anMap[nRow][i] != BLANK)break;}//判断这条直线上是否都为空白区域,如果全为空白区域,则横向连通return false;
}//列号相同时,判断纵向是否连通
bool CGameLogic::LinkInCol(int anMap[][4], Vertex v1, Vertex v2) {int nRow1 = v1.row;int nRow2 = v2.row;int nCol = v1.col;//保证nRow1的值大于nRow2if (nRow1 > nRow2){//数据交换int nTemp = nRow1;nRow1 = nRow2;nRow2 = nTemp;}//直通for (int i = nRow1 + 1; i <= nRow2; i++){if (i == nRow2)return true;if (anMap[i][nCol] != BLANK)break;}//判断这条直线上是否都为空白区域,如果全为空白区域,则纵向连通return false;
}
两条直线消子
代码如下(示例):
// 判断(nRow1,nCol1)到(nRow2,nCol2)能否连通(两条直线消子)
bool CGameLogic::OneCornerLink(int anMap[][4], Vertex v1, Vertex v2)
{//直角能够消子,那么顶点一定在与两个点的行和列相交的点,只有这两个点为空,才有可能实现两条直线消子int nRow1 = v1.row;int nCol1 = v1.col;int nRow2 = v2.row;int nCol2 = v2.col;//确保nRow1<nRow2if (nRow1 > nRow2){int nTemp = nRow1;nRow1 = nRow2;nRow2 = nTemp;nTemp = nCol1;nCol1 = nCol2;nCol2 = nTemp;}if (nCol1 > nCol2){//判断(nRow1 + 1, nCol1)到(nRow2,nCol2 + 1)能否连通if (LineY(anMap, nRow1 + 1, nRow2, nCol1) && LineX(anMap, nRow2, nCol1, nCol2 + 1)){Vertex v = { nRow2,nCol1,BLANK };AddVertex(v);return true;}//判断(nRow2 - 1, nCol2)到(nRow1,nCol1 - 1)能否连通if (LineY(anMap, nRow2 - 1, nRow1, nCol2) && LineX(anMap, nRow1, nCol2, nCol1 - 1)){Vertex v = { nRow1,nCol2,BLANK };AddVertex(v);return true;}}else{//判断(nRow1 + 1, nCol1)到(nRow2,nCol2 - 1)能否连通if (LineY(anMap, nRow1 + 1, nRow2, nCol1) && LineX(anMap, nRow2, nCol1, nCol2 - 1)){Vertex v = { nRow2,nCol1,BLANK };AddVertex(v);return true;}//判断(nRow2 - 1, nCol2)到(nRow1,nCol1 + 1)能否连通if (LineY(anMap, nRow2 - 1, nRow1, nCol2) && LineX(anMap, nRow1, nCol2, nCol1 + 1)){Vertex v = { nRow1,nCol2,BLANK };AddVertex(v);return true;}}return false;
三条直线消子
代码如下(示例):
//判断(nRow1,nCol1)到(nRow2,nCol2)能否连通(三条直线消子)
bool CGameLogic::TwoCornerLink(int anMap[][4], Vertex v1, Vertex v2)
{int nRow1 = v1.row;int nCol1 = v1.col;int nRow2 = v2.row;int nCol2 = v2.col;bool IsTemp = false;//确保nRow1<nRow2if (nRow1 > nRow2){//数据交换int nTemp = nRow1;nRow1 = nRow2;nRow2 = nTemp;nTemp = nCol1;nCol1 = nCol2;nCol2 = nTemp;IsTemp = true; //表明两个点交换}if (nCol1 > nCol2){//找到一条与Y轴平行的连通直线段for (int nCol = 0; nCol < 4; nCol++){if (anMap[nRow1][nCol] == BLANK && anMap[nRow2][nCol] == BLANK){if (LineY(anMap, nRow1, nRow2, nCol)) //判断该条Y轴直线是否连通{//连通的直线在选中的两个点的左边if (nCol2 > nCol && LineX(anMap, nRow1, nCol - 1, nCol) && LineX(anMap, nRow2, nCol, nCol2 - 1)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow1;Vx1.col = nCol;Vx2.row = nRow2;Vx2.col = nCol;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}//连通的直线在选中的两个点的中间if (nCol1 > nCol && nCol > nCol2 && LineX(anMap, nRow1, nCol, nCol1 - 1) && LineX(anMap, nRow2, nCol2 + 1, nCol)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow1;Vx1.col = nCol;Vx2.row = nRow2;Vx2.col = nCol;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}//连通的直线在选中的两个点的右边if (nCol > nCol1 && LineX(anMap, nRow1, nCol1 + 1, nCol) && LineX(anMap, nRow2, nCol, nCol2 + 1)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow1;Vx1.col = nCol;Vx2.row = nRow2;Vx2.col = nCol;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}}}}//找到一条与X轴平行的连通直线段for (int nRow = 0; nRow < 4; nRow++){if (anMap[nRow][nCol1] == BLANK && anMap[nRow][nCol2] == BLANK){if (LineX(anMap, nRow, nCol1, nCol2)) //判断该条Y轴直线是否连通{//连通的直线在选中的两个点的上面if (nRow1 > nRow && LineY(anMap, nRow1 - 1, nRow, nCol1) && LineY(anMap, nRow, nRow2 - 1, nCol2)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow;Vx1.col = nCol1;Vx2.row = nRow;Vx2.col = nCol2;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}//连通的直线在选中的两个点的中间if (nRow2 > nRow && nRow > nRow1 && LineY(anMap, nRow1 + 1, nRow, nCol1) && LineY(anMap, nRow, nRow2 - 1, nCol2)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow;Vx1.col = nCol1;Vx2.row = nRow;Vx2.col = nCol2;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}//连通的直线在选中的两个点的下面if (nRow > nRow2 && LineY(anMap, nRow1 + 1, nRow, nCol1) && LineY(anMap, nRow, nRow2 + 1, nCol2)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow;Vx1.col = nCol1;Vx2.row = nRow;Vx2.col = nCol2;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}}}}}else{//找到一条与Y轴平行的连通直线段for (int nCol = 0; nCol < 4; nCol++){if (anMap[nRow1][nCol] == BLANK && anMap[nRow2][nCol] == BLANK){if (LineY(anMap, nRow1, nRow2, nCol)) //判断该条Y轴直线是否连通{//连通的直线在选中的两个左边if (nCol1 > nCol && LineX(anMap, nRow1, nCol1 - 1, nCol) && LineX(anMap, nRow2, nCol, nCol2 - 1)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow1;Vx1.col = nCol;Vx2.row = nRow2;Vx2.col = nCol;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}//连通的直线在选中的两个点之间if (nCol2 > nCol && nCol > nCol1 && LineX(anMap, nRow1, nCol1 + 1, nCol) && LineX(anMap, nRow2, nCol, nCol2 - 1)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow1;Vx1.col = nCol;Vx2.row = nRow2;Vx2.col = nCol;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}//连通的直线在选中的两个点右边if (nCol > nCol2 && LineX(anMap, nRow1, nCol1 + 1, nCol) && LineX(anMap, nRow2, nCol, nCol2 + 1)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow1;Vx1.col = nCol;Vx2.row = nRow2;Vx2.col = nCol;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}}}}//找到一条与X轴平行的连通直线段for (int nRow = 0; nRow < 4; nRow++){if (anMap[nRow][nCol1] == BLANK && anMap[nRow][nCol2] == BLANK){if (LineX(anMap, nRow, nCol1, nCol2)) //判断该条Y轴直线是否连通{//连通直线在两个点上面if (nRow1 > nRow && LineY(anMap, nRow1 - 1, nRow, nCol1) && LineY(anMap, nRow, nRow2 - 1, nCol2)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow;Vx1.col = nCol1;Vx2.row = nRow;Vx2.col = nCol2;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}//连通直线在两个点之间if (nRow2 > nRow && nRow > nRow1 && LineY(anMap, nRow1 + 1, nRow, nCol1) && LineY(anMap, nRow, nRow2 - 1, nCol2)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow;Vx1.col = nCol1;Vx2.row = nRow;Vx2.col = nCol2;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}//连通直线在两个点下面if (nRow > nRow2 && LineY(anMap, nRow1 + 1, nRow, nCol1) && LineY(anMap, nRow, nRow2 + 1, nCol2)){//保存节点Vertex Vx1;Vertex Vx2;Vx1.row = nRow;Vx1.col = nCol1;Vx2.row = nRow;Vx2.col = nCol2;if (IsTemp == false){AddVertex(Vx1);AddVertex(Vx2);return true;}else{AddVertex(Vx2);AddVertex(Vx1);return true;}}}}}}//找到一条与X轴平行的连通直线段return false;
}
初始化游戏地图
代码如下(示例):
// 初始化游戏地图
void CGameLogic::InitMap(CGraph& graph)
{//游戏地图数组初始化srand((int)time(NULL));//设置种子//生成16种花色的地图int anTemp[MRow][MCol];int a = 0;//初始的第一张图片序号for (int j = 0; j < MCol; j++) {for (int i = 0; i < MRow; i++) {anTemp[i][j] = j;}}//打乱地图花色顺序for (int i = 0; i < MRow ; i++) {for (int j = 0; j < MCol; j++) {int i1 = rand() % MRow;int j1= rand() % MCol;//交换两个点的花色int t = anTemp[i][j];anTemp[i][j] = anTemp[i1][j1];anTemp[i1][j1] = t;}}//初始化顶点for (int i = 0; i < MRow; i++) {for (int j = 0; j < MCol; j++) {graph.AddVertex(anTemp[i][j]); }}//初始化边for (int i = 0; i < MRow; i++) {for (int j = 0; j < MCol; j++) {UpdateArc(graph, i, j);}}}
搜寻路径
代码如下(示例):
//根据深度优先搜索算法判断是否连通
bool CGameLogic::SearchPath(CGraph& graph, int nV0, int nV1)
{//获取顶点数int nVexnum = graph.GetVexnum();//遍历图中nV0行,从0列到nVexnum列,值为true的点for (int nVi = 0; nVi < nVexnum; nVi++){if (graph.GetArc(nV0, nVi) && !IsExsit(nVi)){//压入当前顶点,假设为路径的一个有效顶点PushVertex(nVi);//当拐点数大于2 时if (m_nCorner > 2){//取出压入的顶点PopVertex(); continue;}//当中间顶点不是nVi时,继续搜寻下一个相邻且相连通的顶点if (nVi != nV1){//当中间顶点不为空时,表示该条路径不通if (graph.GetVertex(nVi) != BLANK){ //取出压入的顶点PopVertex(); continue;}//如果nVi是一个已消除的点,则判断(nVi,nV1)是否连通if (SearchPath(graph, nVi, nV1)){return true;}}else//表示已经找到一条连通路径,则返回true{return true;}PopVertex(); //取出压入的顶点,与PushWertex()对应}}return false;
}
提示和重排
代码如下(示例):
//搜寻可消子的有效路径,依次判断地图中同色元素是否可以连通
bool CGameLogic::SearchValidPath(CGraph& graph)
{//得到顶点数int nVexnum = graph.GetVexnum();for (int i = 0; i < nVexnum; i++){//得到第一个非空顶点if (graph.GetVertex(i) == BLANK)continue;//得到第二个非同一个顶点for (int j = 0; j < nVexnum; j++){if (i != j){if (graph.GetVertex(i) == graph.GetVertex(j))//第i个点和第j个点同色{//压入第一个点PushVertex(i);if (SearchPath(graph, i, j) == true)//能够连通{return true;}//取出压入的顶点时,与PushVertex(i)对应PopVertex();}}}}return false;
}//随机任选地图中两个顶点,将元素进行交换,这样进行100次
void CGameLogic::ResetGraph(CGraph& graph)
{//设置种子srand((int)time(NULL));//随机交换两个顶点的值for (int i = 0; i < 100; i++){//随机得到两个坐标int n1 = rand() % MAX_VERTEX_NUM;int n2 = rand() % MAX_VERTEX_NUM;//交换两个数值graph.Change(n1, n2);}//更新弧信息for (int i = 0; i < MRow; i++){for (int j = 0; j < MCol; j++){UpdateArc(graph, i, j);}}}
3.测试用例设计
选用网上找来的图片作为游戏背景图片。
用图片素材来随机生成不同花色的游戏地图。
4.测试效果
总结
详情可参考以下链接
链接:冲冲冲~
提取码:8gc7
复制这段内容后打开百度网盘手机App,操作更方便哦
武汉理工大学数据结构综合实验——连连看游戏综合实践相关推荐
- matlab综合实验研究,MATLAB综合实验报告.doc
MATLAB综合实验报告MATLAB综合实验报告 综合实验报告 实验目的:学会用MATLAB解决本专业的实际问题. 实验任务:根据已知数据用MATLAB拟合出干涉滤光片的波长与光强的关系曲线.拟合出有 ...
- 武汉理工大学c语言pta选择题答案,武汉理工大学c语言实验及答案.doc
武汉理工大学c语言实验及答案 实验二 选择结构的程序设计 1.编程计算下面的分段函数. 4x-8 -1≤x<0 y= 3x2+10x-1 0≤x<1 8x3-3x2+2x-1 1≤x< ...
- 武汉理工大学c语言实验 编程解决鸡兔同笼问题,C语言程序设计实验指导
本书是<C语言程序设计基础>(李民.钟钰.秦珀石主编)的配套实验教材.实验教材与理论教材相辅相成,采用边讲边练的方式,帮助读者切实提高编程能力.本书共分10章,第1章为C语言环境介绍.第2 ...
- 计算机硬件综合 实验,《计算机硬件综合实验》b答案
<计算机硬件综合实验>b答案 (3页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 考试试卷第 1 页 共 3 页一.简答题一 ...
- 武汉理工大学数据结构综合实验——二叉树与赫夫曼图片压缩
文章目录 实验目的 主要仪器设备及耗材 一.实验要求 二.分析与设计 1.数据结构的设计 2.核心算法设计 生成Huffman树的算法 生成Huffman编码的算法 压缩编码的算法 3.测试用例设计 ...
- 武汉理工大学数据结构综合实验——图与景区信息管理系统实践
文章目录 实验目的 主要仪器设备及耗材 一.实验要求 二.分析与设计 1.数据结构的设计 2.核心算法设计 改进DFS算法 搜索最短路径 Prim算法(构建最小生成树) 3.测试用例设计 4.测试结果 ...
- 微型计算机原理综合实验,微机原理综合实验指导书
三.撰写报告的要求: 1. 写出程序设计思想 2. 画出流程图 3. 源程序清单 4. 写出调试过程,提供程序运行结果 5. 写出调试中碰到的问题,以及解决办法,获得的收获 6. 测试结果分析 二.综 ...
- 2022年武汉理工大学数据库系统综合实验5.1,5.2安全性语言及多用户事务管理
实验5.1 自主存取控制实验 实验任务 一,数据库用户任务 1.创建用户user_1和user_2,密码都为1234 create user 'user_1'@'localhost' identifi ...
- c语言设计实验报告答案,武汉理工大学《C语言程序设计》实验报告答案
武汉理工大学<C语言程序设计>实验报告答案 注:在Visual C++ 6.0编译环境中亲自调试通过,但不保证在Turbo C中通过. 实验二 选择结构的程序设计 (题目当初没抄下来,这是 ...
最新文章
- cesium雷达图_20个简化开发任务的 JavaScript库
- Vue_异步加载_vue-resource(不再维护)
- makemoney 秘密
- java并发中的延迟初始化
- 使用scrum开发软件的一般过程是什么?_黑色灌封胶的使用工艺复杂吗?使用过程中应该注意什么?...
- Win10下安装LabelImg以及使用(绝对是全网最简单的教程)
- python对编写神经网络作用_神经网络(BP)算法Python实现及应用
- SpringMVC后台数据校验
- 万字长文!搞定逃不脱的 DNS 面试题
- WINCCV7.5入门指南学习简介
- 谷歌推出全能扒谱AI:只要听一遍歌曲,钢琴小提琴的乐谱全有了
- 腾讯短视频SDK代码层面上录制功能的实现,短视频APP开发第一步
- 研究生查分方式-查分时间大汇总-文都管联院
- VS2019 测试使用libusb
- 数加平台——阿里大数据OS实践
- 什么是LHS查询和RHS查询
- UltraISO 绿色多国语言版
- SCALABILITY可伸缩性和EXTENSIBILITY可扩展性的区别
- Transferable Joint Attribute-Identity Deep Learning for Unsupervised Person Re-Identification阅读总结
- 2016.11.29遇到的问题