ImageVerifierCode 换一换
格式:DOCX , 页数:25 ,大小:1.64MB ,
资源ID:3312611      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/3312611.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(武汉理工大学数据结构与算法综合实验连连看.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

武汉理工大学数据结构与算法综合实验连连看.docx

1、武汉理工大学数据结构与算法综合实验连连看 学生学号 Xxx实验课成绩学 生 实 验 报 告 书实验课程名称数据结构与算法综合实验开课学院计算机科学与技术学院指导教师姓名xx学生姓名xx学生专业班级xxxx2015-2016学年第2学期实验课程名称: 数据结构与算法综合实验 实验项目名称连连看游戏综合实践报告成绩实验者xxx专业班级xxxxx组别同组者 完成日期年 月 日第一部分:实验分析与设计(可加页)一、实验目的和要求1.目的 调研连连看游戏,了解连连看游戏的功能和规则等。 掌握集成开发工具。 掌握C+的基础编程。 了解MFC框架,包括MFC Dialog应用程序和GDI编程。 了解线性结构

2、,重点掌握数组和栈操作,掌握数组的遍历、消子和胜负判断等算法。 了解企业软件开发过程,了解系统需求分析和设计,应用迭代开发思路进行项目开发。 养成良好的编程习惯和培养软件工程化思维,综合应用“C+编程、MFC Dialog、算法、线性结构”等知识,开发“连连看游戏”桌面应用程序,达到掌握和应用线性核心知识的目的。2.要求 待开发的连连看游戏称为“欢乐连连看”,使用二维数组来保存游戏地图的数据,实现连连看的核心功能。欢乐连连看的功能有:主界面、开始游戏、消子、判断胜负、提示、重排、计时、游戏模式。 主界面 游戏主界面就是进行各项操作的入口。 开始游戏 玩家选择开始游戏模式,进入游戏后,选择开始游

3、戏,系统根据设置的主题风格生成图片布局,以供玩家点击消除。 游戏地图大小为640*400,是一个16行乘10列的矩形,分成160个小正方形,存放160张图片,每张图片大小为40*40。 消子 对玩家选中的两张图片进行判断,判断是否符合消除规则。只有符合以下规则的图片对才能被消除:v 一条直线连通v 两条直线连通v 三条直线连通 如果可以消除,从游戏地图中提示连接路线,然后消除这两张图片,并计算相应的积分。如果不能消除,则保持原来的游戏地图。 判断胜负 当游戏完成后,需要判断游戏胜负。不同模式下判断胜负的规则不同。v 基本模式时,如果在五分钟内将游戏地图的所有图片都消除,则提示玩家胜利。v 休闲

4、模式时,如果游戏地图中所有图片都被消除,则提示玩家获胜。 提示 可以提示界面上能够消除的一对图片。 计时 设定一定时间来辅助游戏是否结束。 重排 根据随机数,重新排列地图上的图片。 游戏模式 游戏模式有:基本模式、休闲模式和关卡模式三种,可以根据是否定时等规则进行设置。二、分析与设计1.数据结构的设计1) 顶点存储 添加global.h文件,定义结构体tagVertex,用于保存游戏地图中一个点的行号、列号、值信息。typedef struct tagVertexint row;/行int col;/列int info;/信息类Vertex;2) 游戏地图存储结构 使用二位数组来保存连连看游戏

5、地图,在给没一种图片一个编号,并将这些编号保存在二位数组中。 用户在屏幕上选择两张图片,对应为数组中的两组坐标。分别实现三个消子判断算法:一条直线连通、两条直线连通、三条直线连通,并使用者三个算法进项消子判断。若符合消子规则,就在屏幕上消除一对图片,并把数组对应元素清空。1游戏地图中图片种类和重复次数与游戏的级别汉难度有关。图片种类越多,重复次数越小,游戏难度越大,反之则越容易。2只有两张相同的图片才能消除。为保证游戏中的图片能够完全消掉,每种图片出现的次数一定是偶数,即2的倍数。3地图的大小与图片元素种类之间的关系地图的行数*地图的列数=图片种类数*每种图片重复的次数。4地图数据的存储a.

6、用int类型的动态二位数组(int *m_pGameMap)存储地图中元素图片的编号。b. 获得某行某列对应的元素编号。2.核心算法设计 随机开局算法1) 计算游戏中元素个数:行数*列数。2) 计算每种花色重复数:行数*列数/花色数。1判断(行数*列数%花色数)是否为0。如果不为0,则进行异常处理。2判断每一种花色的重复数能否被2整除,如果不能被二整除,则进行异常处理。3)按从左到右,从上到下,将花色数填入游戏地图。实现代码如下: int nRepeatNum = nRows * nCols / nPicNums; int count = 0; for (int i = 0; inPicNum

7、s; i+) for (int j = 0; j col2) int temp=col1; col1=col2; col2=temp; /判断两个顶点间是否有不为空的图片 for(int i=col1+1;irow2) int temp=row1; row1=row2; row2=temp; for(int i=row1+1;i=row2;i+) if(i=row2) return true; if(m_Mapicol!=BLANK) break; return false; 两条直线消子算法 若一条直线无法连通,则判断两条直线的情况。在CGameLogic类中定义OneCornerLink(

8、)函数判断两点是否能两条直线连通。 先判断两个顶点的X和Y方向的直线相交的两个顶点,是否为空。若能构成两条指向连通,那么相交的顶点必须为空才行。 若顶点有一个为空,则判断该顶点与两个顶点,横向与纵向一条直线是否连通,若都连通,则表示两条直线消子成功,否则不能相消。实现代码如下:bool CGameLogic:OneCornerLink(int m_Map1015,Vertex v1,Vertex v2) int row1=v1.row; int col1=v1.col; int row2=v2.row; int col2=v2.col; /判断相交的顶点是否为空 if(m_Maprow1col

9、2=BLANK) /判断两个同行的顶点是否一条直线连通 if(LineY(m_Map,row1,row2,col2)&LineX(m_Map,row1,col1,col2) Vertex V=row1,col2,BLANK; AddVertex(V); return true; if(m_Maprow2col1=BLANK) /判断两个同列顶点是否一条直线连通 if(LineY(m_Map,row1,row2,col1)&LineX(m_Map,row2,col1,col2) Vertex V=row2,col1,BLANK; AddVertex(V); return true; return

10、 false; 三条直线消子算法 若两条直线无法连通,则判断三条直线的情况。在CGameLogic类中定义TwoCornerLink()函数判断两点能否三条直线连通。 三条直线消子时,假设选择的两张图片的位置为(nRow1,nCol1)和(nRow2,nCol2),则先寻找与Y轴平行的连通线段。 如果Y轴没有找到可以连通的三条直线,则寻找以X轴平行的连通线段。1) 搜索关键路径 假设玩家选择的两个顶点为V0(row0,col0),V3(row3,col3),步骤如下:第一步:从地图的第一行开始扫描,当前扫描到nRow行。第二步:设置拐点:V1(nRow,col0),V2(nRow,col3)。

11、第三步:判断V1和V2是否水平方向向上连通,如果连通,则V1到V2的连线即为关键路径。如果不连通则接着扫描下一行,重复第二四步。2) 判断三条直线连通 采用枚举法判断三条直线连通,假设玩家选择两个顶点为V0和V3,判断三条直线连通的具体实现的具体步骤如下:1找到其中一条关键路径V1,V2。2判断V1和V0是否连通。3判断V2和V3是否连通。4如果同时满足V1和V0连通,V2和V3连通,则V0和V3满足三条直线连通。否则,在此关键路径下V0和V3不连通,找到下一条关键路径,重复24,直到判断出V0和V3是否连通。3)保存连通路径 使用栈来保存连通路径中的关键点:起始点V0,拐点V1,拐点V2和终

12、点V3。保存连通路径的步骤如下:1保存其实点V0。2判断是否存在能够满足三条直线消子的关键路径V1、V2。3如果存在,保存顶点V1、V2、V3,如果不存在,在删除起始点V0。实现代码如下:bool CGameLogic:TwoCornerLink(int m_Map1016,Vertex v1,Vertex v2) int row1=v1.row; int col1=v1.col; int row2=v2.row; int col2=v2.col; for(int col=0;col16;col+) if(m_Maprow1col=BLANK&m_Maprow2col=BLANK) if(Li

13、neY(m_Map,row1,row2,col) if(LineX(m_Map,row1,col1,col)&LineX(m_Map,row2,col2,col) Vertex V1=row1,col,BLANK; Vertex V2=row2,col,BLANK; AddVertex(V1); AddVertex(V2); return true; for(int row=0;row10;row+) if(m_Maprowcol1=BLANK&m_Maprowcol2=BLANK) if(LineX(m_Map,row,col1,col2) if(LineY(m_Map,row,row1,c

14、ol1)&LineY(m_Map,row,row2,col2) Vertex V1=row,col1,BLANK; Vertex V2=row,col2,BLANK; AddVertex(V1); AddVertex(V2); return true; return false;4)胜负判断算法 当所有元素被消掉,进行胜负判断,遍历地图中所有元素的值,当所有元素都为空时,表示获胜,游戏结束,否则继续游戏。实现代码如下: if (m_GameProgress.GetPos() EnableWindow(TRUE); else exit(0); IsPlaying = false; else if

15、 (m_GameProgress.GetPos() 0 & cgc.IsBlank(cgc.m_Map) KillTimer(PLAY_TIMER_ID); int result; result = MessageBox(_T(获胜!是否重新开始游戏?), _T(提示); if (result = IDOK) GetDlgItem(IDC_BUTTON_START)-EnableWindow(TRUE); else exit(0); 5)重排 当进行游戏的过程中会出现无法再进行消子的情况,点击重排按钮就可以将剩下子进行随机重排以便客户能够正常进行消子操作。首先在CGameLogic类中定义一个

16、DisOrderMap()函数来对剩下的元素进行重排,实现代码如下:void CGameLogic:DisOrderMap(int m_Map1016) int nRows = 10; int nCols = 16; srand(int)time(NULL); int nVertexNum = nRows * nCols; for (int i = 0; inVertexNum; i+) /随机获得两个坐标 int nIndex1 = rand() % nVertexNum; int nIndex2 = rand() % nVertexNum; int nTemp = m_MapnIndex1

17、 / nColsnIndex1 % nCols; m_MapnIndex1 / nColsnIndex1 % nCols = m_MapnIndex2 / nColsnIndex2 % nCols; m_MapnIndex2 / nColsnIndex2 % nCols = nTemp; 然后在CGameControl类中定义一个DisOrder()函数来调用DisOrderMap()函数,最后再CGameDlg类的OnBnClickedButtonReset()函数中调用DisOrder()函数,实现代码如下:void CGameDlg:OnBnClickedButtonReset() /

18、TODO: 在此添加控件通知处理程序代码 m_dcMem.BitBlt(0, 0, 800, 600, &m_dcBG, 0, 0, SRCCOPY); InvalidateRect(FALSE); m_gameControl.DisOrder(); UpDateMap();6)帮助 在原有的基础上重新插入一个对话框,重新定义一个CHelpDialog类,在这个类中将写有相关游戏说明的图片加载进界面中去,加上滚动条。实现代码如下:BOOL CHelpDialog:OnInitDialog() CDialogEx:OnInitDialog(); ASSERT(IDM_ABOUTBOX & 0xF

19、FF0) = IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX LoadIcon(IDR_MAINFRAME);/IDR_ICON为图标资源名 SetIcon(m_hIcon, TRUE); / Set big icon SetIcon(m_hIcon, FALSE); / Set small icon /加载图片资源 HANDLE bmp = :LoadImage(NULL, _T(themepictureHelp1.bmp), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); /获得当前对话框的视频内存 CClientDC dc(this);

20、/创建与视频内存兼容的内存DC m_dcHelp.CreateCompatibleDC(&dc); /将位图资源选入DC m_dcHelp.SelectObject(bmp); /初始化内存DC m_dcMen.CreateCompatibleDC(&dc); CBitmap bmpMem; bmpMem.CreateCompatibleBitmap(&dc, 500, 400); m_dcMen.SelectObject(&bmpMem); /绘制背景到内存中 m_dcMen.BitBlt(0, 0, 800, 600, &m_dcHelp, 0, 0, SRCCOPY); /绘制帮助信息显

21、示区域 this-GetDlgItem(IDC_BUTTON_HELP)-GetWindowRect(&m_rtHelp); this-ScreenToClient(&m_rtHelp); /绘制帮助信息 UpdateHelp(0);/表示滚动条的初始位置为0 /设置滚动条范围 CBitmap bmpHelp; bmpHelp.Attach(bmp); BITMAP bmpInfo; bmpHelp.GetBitmap(&bmpInfo); /设置滚动条范围 (CScrollBar*)this-GetDlgItem(IDC_SCROLLBAR)-SetScrollRange(0,bmpInfo

22、,bmpHelp); return TRUE; / return TRUE unless you set the focus to a control / 异常: OCX 属性页应返回 FALSE / TODO: 在此添加额外的初始化滚动条设置:void CHelpDialog:OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) UINT Pos; int nMaxPos, nMinPos; / TODO: 在此添加消息处理程序代码和/或调用默认值 switch (nSBCode) case SB_LINEUP: Pos -=

23、-1; break; case SB_LINEDOWN: Pos += 1; break; case SB_PAGEUP: Pos -= 10; break; case SB_PAGEDOWN: Pos += 10; break; case SB_TOP: Pos = nMinPos; case SB_BOTTOM: Pos = nMaxPos; case SB_THUMBPOSITION:/点击在滑块上 Pos = nPos; default: break; pScrollBar-SetScrollPos(Pos, TRUE);/设置滚动条当前点的值 UpdateHelp(Pos); CDi

24、alogEx:OnVScroll(nSBCode, nPos, pScrollBar);7)暂停游戏 点击暂停游戏按钮,按钮的文字由”暂停游戏“变成”继续游戏“字样,并且用户不能进行游戏,同时进度条停止计时。实现代码如下:void CGameDlg:OnBnClickedBtnGameStop() CString btnPauseName; CString goGame(继续游戏); CString pauGame(暂停游戏); GetDlgItemText(IDC_BTN_GAME_STOP,btnPauseName); if( btnPauseName = pauGame ) /计时器停止

25、计时 KillTimer(PLAY_TIMER_ID); SetDlgItemText(IDC_BTN_GAME_STOP,goGame); m_bPlaying = FALSE; m_dcMem.BitBlt(m_rtGameRect.left+40,m_rtGameRect.top+40,m_rtGameRect.Width(),m_rtGameRect.Height(),&m_stopGame,m_rtGameRect.left,m_rtGameRect.top,SRCCOPY); InvalidateRect(&m_rtGameRect,FALSE); else /计时器开始计时 SetTim

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1