文章目录

  • 实验目的
  • 主要仪器设备及耗材
  • 一、实验要求
  • 二、分析与设计(非线性结构)
    • 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,操作更方便哦

武汉理工大学数据结构综合实验——连连看游戏综合实践相关推荐

  1. matlab综合实验研究,MATLAB综合实验报告.doc

    MATLAB综合实验报告MATLAB综合实验报告 综合实验报告 实验目的:学会用MATLAB解决本专业的实际问题. 实验任务:根据已知数据用MATLAB拟合出干涉滤光片的波长与光强的关系曲线.拟合出有 ...

  2. 武汉理工大学c语言pta选择题答案,武汉理工大学c语言实验及答案.doc

    武汉理工大学c语言实验及答案 实验二 选择结构的程序设计 1.编程计算下面的分段函数. 4x-8 -1≤x<0 y= 3x2+10x-1 0≤x<1 8x3-3x2+2x-1 1≤x< ...

  3. 武汉理工大学c语言实验 编程解决鸡兔同笼问题,C语言程序设计实验指导

    本书是<C语言程序设计基础>(李民.钟钰.秦珀石主编)的配套实验教材.实验教材与理论教材相辅相成,采用边讲边练的方式,帮助读者切实提高编程能力.本书共分10章,第1章为C语言环境介绍.第2 ...

  4. 计算机硬件综合 实验,《计算机硬件综合实验》b答案

    <计算机硬件综合实验>b答案 (3页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 考试试卷第 1 页 共 3 页一.简答题一 ...

  5. 武汉理工大学数据结构综合实验——二叉树与赫夫曼图片压缩

    文章目录 实验目的 主要仪器设备及耗材 一.实验要求 二.分析与设计 1.数据结构的设计 2.核心算法设计 生成Huffman树的算法 生成Huffman编码的算法 压缩编码的算法 3.测试用例设计 ...

  6. 武汉理工大学数据结构综合实验——图与景区信息管理系统实践

    文章目录 实验目的 主要仪器设备及耗材 一.实验要求 二.分析与设计 1.数据结构的设计 2.核心算法设计 改进DFS算法 搜索最短路径 Prim算法(构建最小生成树) 3.测试用例设计 4.测试结果 ...

  7. 微型计算机原理综合实验,微机原理综合实验指导书

    三.撰写报告的要求: 1. 写出程序设计思想 2. 画出流程图 3. 源程序清单 4. 写出调试过程,提供程序运行结果 5. 写出调试中碰到的问题,以及解决办法,获得的收获 6. 测试结果分析 二.综 ...

  8. 2022年武汉理工大学数据库系统综合实验5.1,5.2安全性语言及多用户事务管理

    实验5.1 自主存取控制实验 实验任务 一,数据库用户任务 1.创建用户user_1和user_2,密码都为1234 create user 'user_1'@'localhost' identifi ...

  9. c语言设计实验报告答案,武汉理工大学《C语言程序设计》实验报告答案

    武汉理工大学<C语言程序设计>实验报告答案 注:在Visual C++ 6.0编译环境中亲自调试通过,但不保证在Turbo C中通过. 实验二 选择结构的程序设计 (题目当初没抄下来,这是 ...

最新文章

  1. cesium雷达图_20个简化开发任务的 JavaScript库
  2. Vue_异步加载_vue-resource(不再维护)
  3. makemoney 秘密
  4. java并发中的延迟初始化
  5. 使用scrum开发软件的一般过程是什么?_黑色灌封胶的使用工艺复杂吗?使用过程中应该注意什么?...
  6. Win10下安装LabelImg以及使用(绝对是全网最简单的教程)
  7. python对编写神经网络作用_神经网络(BP)算法Python实现及应用
  8. SpringMVC后台数据校验
  9. 万字长文!搞定逃不脱的 DNS 面试题
  10. WINCCV7.5入门指南学习简介
  11. 谷歌推出全能扒谱AI:只要听一遍歌曲,钢琴小提琴的乐谱全有了
  12. 腾讯短视频SDK代码层面上录制功能的实现,短视频APP开发第一步
  13. 研究生查分方式-查分时间大汇总-文都管联院
  14. VS2019 测试使用libusb
  15. 数加平台——阿里大数据OS实践
  16. 什么是LHS查询和RHS查询
  17. UltraISO 绿色多国语言版
  18. SCALABILITY可伸缩性和EXTENSIBILITY可扩展性的区别
  19. Transferable Joint Attribute-Identity Deep Learning for Unsupervised Person Re-Identification阅读总结
  20. 2016.11.29遇到的问题

热门文章

  1. 【PyCharm警告】选择性忽略 PEP8 警告
  2. 进击的局座:悄悄话读后感
  3. python可视化工具:matplotlib+pyecharts使用详解
  4. 推荐几个能被惊艳到的程序员必备的画图工具
  5. NovelAI二次元绘画体验
  6. Azkaban快速入门
  7. Codeforces 104C Cthulhu dfs暴力 || 点双连通缩点
  8. python 频率直方图
  9. uniapp项目实现扫描二维码和NFC识别功能
  10. 大学生数学建模优秀论文发表