文章目录
实验目的
(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的值小于nCol2
if (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的值大于nRow2
if (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<nRow2
if (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