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

上传人:无*** 文档编号:101416898 上传时间:2022-06-05 格式:DOC 页数:29 大小:1.72MB
返回 下载 相关 举报
武汉理工大学数据结构及算法综合实验连连看_第1页
第1页 / 共29页
武汉理工大学数据结构及算法综合实验连连看_第2页
第2页 / 共29页
武汉理工大学数据结构及算法综合实验连连看_第3页
第3页 / 共29页
点击查看更多>>
资源描述
-学生*实验课成绩学生实验报告书实验课程名称数据构造与算法综合实验开课学院计算机科学与技术学院指导教师*学生*学生专业班级*2015-2016学年第2学期. z.-实验课程名称:数据构造与算法综合实验实验工程名称连连看游戏综合实践报告成绩实验者*专业班级*组别同组者完成日期年月日第一局部:实验分析与设计可加页一、实验目的和要求1.目的l 调研连连看游戏,了解连连看游戏的功能和规则等。l 掌握集成开发工具。l 掌握C+的根底编程。l 了解MFC框架,包括MFC Dialog应用程序和GDI编程。l 了解线性构造,重点掌握数组和栈操作,掌握数组的遍历、消子和胜负判断等算法。l 了解企业软件开发过程,了解系统需求分析和设计,应用迭代开发思路进展工程开发。l 养成良好的编程习惯和培养软件工程化思维,综合应用C+编程、MFC Dialog、算法、线性构造等知识,开发连连看游戏桌面应用程序,到达掌握和应用线性核心知识的目的。2.要求待开发的连连看游戏称为欢乐连连看,使用二维数组来保存游戏地图的数据,实现连连看的核心功能。欢乐连连看的功能有:主界面、开场游戏、消子、判断胜负、提示、重排、计时、游戏模式。l 主界面游戏主界面就是进展各项操作的入口。l 开场游戏玩家选择开场游戏模式,进入游戏后,选择开场游戏,系统根据设置的主题风格生成图片布局,以供玩家点击消除。游戏地图大小为640*400,是一个16行乘10列的矩形,分成160个小正方形,存放160*图片,每*图片大小为40*40。l 消子对玩家选中的两*图片进展判断,判断是否符合消除规则。只有符合以下规则的图片对才能被消除:v 一条直线连通v 两条直线连通v 三条直线连通如果可以消除,从游戏地图中提示连接路线,然后消除这两*图片,并计算相应的积分。如果不能消除,则保持原来的游戏地图。l 判断胜负当游戏完成后,需要判断游戏胜负。不同模式下判断胜负的规则不同。v 根本模式时,如果在五分钟内将游戏地图的所有图片都消除,则提示玩家胜利。v 休闲模式时,如果游戏地图中所有图片都被消除,则提示玩家获胜。l 提示可以提示界面上能够消除的一对图片。l 计时设定一定时间来辅助游戏是否完毕。l 重排根据随机数,重新排列地图上的图片。l 游戏模式游戏模式有:根本模式、休闲模式和关卡模式三种,可以根据是否认时等规则进展设置。二、分析与设计1.数据构造的设计1) 顶点存储添加global.h文件,定义构造体tagVerte*,用于保存游戏地图中一个点的行号、列号、值信息。typedef struct tagVerte*int row;/行int col;/列int info;/信息类Verte*;2) 游戏地图存储构造使用二位数组来保存连连看游戏地图,在给没一种图片一个编号,并将这些编号保存在二位数组中。用户在屏幕上选择两*图片,对应为数组中的两组坐标。分别实现三个消子判断算法:一条直线连通、两条直线连通、三条直线连通,并使用者三个算法进项消子判断。假设符合消子规则,就在屏幕上消除一对图片,并把数组对应元素清空。 游戏地图中图片种类和重复次数与游戏的级别汉难度有关。图片种类越多,重复次数越小,游戏难度越大,反之则越容易。 只有两*一样的图片才能消除。为保证游戏中的图片能够完全消掉,每种图片出现的次数一定是偶数,即2的倍数。 地图的大小与图片元素种类之间的关系地图的行数*地图的列数=图片种类数*每种图片重复的次数。 地图数据的存储a. 用int类型的动态二位数组(int *m_pGameMap)存储地图中元素图片的编号。b. 获得*行*列对应的元素编号。2.核心算法设计l 随机开局算法1) 计算游戏中元素个数:行数*列数。2) 计算每种花色重复数:行数*列数/花色数。 判断行数*列数%花色数是否为0。如果不为0,则进展异常处理。 判断每一种花色的重复数能否被2整除,如果不能被二整除,则进展异常处理。3) 按从左到右,从上到下,将花色数填入游戏地图。实现代码如下:int nRepeatNum = nRows * nCols / nPiums;int count = 0;for (int i = 0; inPiums; i+)for (int j = 0; j col2)inttemp=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)returntrue;if(m_Mapicol!=BLANK)break;returnfalse;l 两条直线消子算法假设一条直线无法连通,则判断两条直线的情况。在CGameLogic类中定义OneCornerLink函数判断两点是否能两条直线连通。先判断两个顶点的*和Y方向的直线相交的两个顶点,是否为空。假设能构成两条指向连通,则相交的顶点必须为空才行。假设顶点有一个为空,则判断该顶点与两个顶点,横向与纵向一条直线是否连通,假设都连通,则表示两条直线消子成功,否则不能相消。实现代码如下:boolCGameLogic:OneCornerLink(intm_Map1015,Verte*v1,Verte*v2)int row1=v1.row;int col1=v1.col;int row2=v2.row;int col2=v2.col;/判断相交的顶点是否为空if(m_Maprow1col2=BLANK)/判断两个同行的顶点是否一条直线连通if(LineY(m_Map,row1,row2,col2)&Line*(m_Map,row1,col1,col2)Verte* V=row1,col2,BLANK;AddVerte*(V);returntrue;if(m_Maprow2col1=BLANK)/判断两个同列顶点是否一条直线连通if(LineY(m_Map,row1,row2,col1)&Line*(m_Map,row2,col1,col2)Verte* V=row2,col1,BLANK;AddVerte*(V);returntrue;returnfalse;l 三条直线消子算法假设两条直线无法连通,则判断三条直线的情况。在CGameLogic类中定义TwoCornerLink()函数判断两点能否三条直线连通。三条直线消子时,假设选择的两*图片的位置为nRow1,nCol1和nRow2,nCol2,则先寻找与Y轴平行的连通线段。如果Y轴没有找到可以连通的三条直线,则寻找以*轴平行的连通线段。1) 搜索关键路径假设玩家选择的两个顶点为V0row0,col0,V3row3,col3,步骤如下:第一步:从地图的第一行开场扫描,当前扫描到nRow行。第二步:设置拐点:V1nRow,col0,V2(nRow,col3)。第三步:判断V1和V2是否水平方向向上连通,如果连通,则V1到V2的连线即为关键路径。如果不连通则接着扫描下一行,重复第二四步。2) 判断三条直线连通采用枚举法判断三条直线连通,假设玩家选择两个顶点为V0和V3,判断三条直线连通的具体实现的具体步骤如下: 找到其中一条关键路径V1,V2。 判断V1和V0是否连通。 判断V2和V3是否连通。 如果同时满足V1和V0连通,V2和V3连通,则V0和V3满足三条直线连通。否则,在此关键路径下V0和V3不连通,找到下一条关键路径,重复24,直到判断出V0和V3是否连通。3) 保存连通路径使用栈来保存连通路径中的关键点:起始点V0,拐点V1,拐点V2和终点V3。保存连通路径的步骤如下: 保存其实点V0。 判断是否存在能够满足三条直线消子的关键路径V1、V2。 如果存在,保存顶点V1、V2、V3,如果不存在,在删除起始点V0。实现代码如下:boolCGameLogic:TwoCornerLink(intm_Map1016,Verte*v1,Verte*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(LineY(m_Map,row1,row2,col)if(Line*(m_Map,row1,col1,col)&Line*(m_Map,row2,col2,col)Verte* V1=row1,col,BLANK;Verte* V2=row2,col,BLANK;AddVerte*(V1); AddVerte*(V2);returntrue;for(int row=0;row10;row+)if(m_Maprowcol1=BLANK&m_Maprowcol2=BLANK)if(Line*(m_Map,row,col1,col2)if(LineY(m_Map,row,row1,col1)&LineY(m_Map,row,row2,col2)Verte* V1=row,col1,BLANK;Verte* V2=row,col2,BLANK;AddVerte*(V1); AddVerte*(V2);returntrue;returnfalse;4) 胜负判断算法当所有元素被消掉,进展胜负判断,遍历地图中所有元素的值,当所有元素都为空时,表示获胜,游戏完毕,否则继续游戏。实现代码如下:if (m_GameProgress.GetPos() EnableWindow(TRUE);else e*it(0);IsPlaying = false;elseif (m_GameProgress.GetPos() 0 & cgc.IsBlank(cgc.m_Map)KillTimer(PLAY_TIMER_ID);int result;result = MessageBo*(_T(获胜!是否重新开场游戏?), _T(提示);if (result = IDOK) GetDlgItem(IDC_BUTTON_START)-EnableWindow(TRUE);else e*it(0);5) 重排当进展游戏的过程中会出现无法再进展消子的情况,点击重排按钮就可以将剩下子进展随机重排以便客户能够正常进展消子操作。首先在CGameLogic类中定义一个DisOrderMap函数来对剩下的元素进展重排,实现代码如下:voidCGameLogic:DisOrderMap(intm_Map1016)int nRows = 10;int nCols = 16;srand(int)time(NULL);int nVerte*Num = nRows * nCols;for (int i = 0; inVerte*Num; i+)/随机获得两个坐标int nInde*1 = rand() % nVerte*Num;int nInde*2 = rand() % nVerte*Num;int nTemp = m_MapnInde*1 / nColsnInde*1 % nCols;m_MapnInde*1 / nColsnInde*1 % nCols = m_MapnInde*2 / nColsnInde*2 % nCols;m_MapnInde*2 / nColsnInde*2 % nCols = nTemp;然后在CGameControl类中定义一个DisOrder函数来调用DisOrderMap函数,最后再CGameDlg类的OnBnClickedButtonReset()函数中调用DisOrder函数,实现代码如下:voidCGameDlg:OnBnClickedButtonReset()/ TODO: 在此添加控件通知处理程序代码m_dcMem.BitBlt(0, 0, 800, 600, &m_dcBG, 0, 0, SRCCOPY);InvalidateRect(FALSE);m_gameControl.DisOrder();UpDateMap();6) 帮助在原有的根底上重新插入一个对话框,重新定义一个CHelpDialog类,在这个类中将写有相关游戏说明的图片加载进界面中去,加上滚动条。实现代码如下:BOOLCHelpDialog:OnInitDialog()CDialogE*:OnInitDialog();ASSERT(IDM_ABOUTBO* & 0*FFF0) = IDM_ABOUTBO*);ASSERT(IDM_ABOUTBO* LoadIcon(IDR_MAINFRAME);/IDR_ICON为图标资源名SetIcon(m_hIcon, TRUE); / Set big iconSetIcon(m_hIcon, FALSE); / Set small icon/加载图片资源HANDLE bmp = :LoadImage(NULL, _T(themepictureHelp1.bmp), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);/获得当前对话框的视频内存CClientDC dc(this);/创立与视频内存兼容的内存DCm_dcHelp.CreatepatibleDC(&dc);/将位图资源选入DCm_dcHelp.SelectObject(bmp);/初始化内存DCm_dcMen.CreatepatibleDC(&dc);CBitmap bmpMem;bmpMem.CreatepatibleBitmap(&dc, 500, 400);m_dcMen.SelectObject(&bmpMem);/绘制背景到内存中m_dcMen.BitBlt(0, 0, 800, 600, &m_dcHelp, 0, 0, SRCCOPY);/绘制帮助信息显示区域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,bmpHelp);returnTRUE; / return TRUE unless you set the focus to a control/ 异常: OC* 属性页应返回 FALSE/ TODO: 在此添加额外的初始化滚动条设置:voidCHelpDialog:OnVScroll(UINTnSBCode, UINTnPos, CScrollBar* pScrollBar)UINT Pos;int nMa*Pos, nMinPos;/ TODO: 在此添加消息处理程序代码和/或调用默认值switch (nSBCode)caseSB_LINEUP:Pos -= -1;break;caseSB_LINEDOWN:Pos += 1;break;caseSB_PAGEUP:Pos -= 10;break;caseSB_PAGEDOWN:Pos += 10;break;caseSB_TOP:Pos = nMinPos;caseSB_BOTTOM:Pos = nMa*Pos;caseSB_THUMBPOSITION:/点击在滑块上Pos = nPos;default:break;pScrollBar-SetScrollPos(Pos, TRUE);/设置滚动条当前点的值UpdateHelp(Pos);CDialogE*:OnVScroll(nSBCode, nPos, pScrollBar);7) 暂停游戏点击暂停游戏按钮,按钮的文字由暂停游戏变成继续游戏字样,并且用户不能进展游戏,同时进度条停顿计时。实现代码如下:voidCGameDlg:OnBnClickedBtnGameStop()CString btnPauseName;CString goGame(继续游戏);CString pauGame(暂停游戏);GetDlgItemTe*t(IDC_BTN_GAME_STOP,btnPauseName);if( btnPauseName = pauGame )/计时器停顿计时KillTimer(PLAY_TIMER_ID);SetDlgItemTe*t(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/计时器开场计时SetTimer(PLAY_TIMER_ID,1000,NULL);SetDlgItemTe*t(IDC_BTN_GAME_STOP,pauGame);m_bPlaying = TRUE;UpdateMap();InvalidateRect(&m_rtGameRect,FALSE);8) 计时先在游戏界面中添加一个进度条控件,在添加一个static te*t文本来记录进度条位置,在CGameDlg类中编写OnTimer函数来实现。实现代码如下:voidCGameDlg:OnTimer(UINT_PTRnIDEvent)if(nIDEvent = PLAY_TIMER_ID&m_bPlaying)m_GameProgress.StepIt();int npos = m_GameProgress.GetPos();if (npos = 0)MessageBo*(_T(时间到,失败);m_bPlaying = FALSE;GetDlgItem(IDC_BTN_GAME_START)-EnableWindow(TRUE);m_dcMem.BitBlt(m_rtGameRect.left,m_rtGameRect.top,m_rtGameRect.Width(),m_rtGameRect.Height(),&m_dcBG,m_rtGameRect.left,m_rtGameRect.top,SRCCOPY);InvalidateRect(&m_rtGameRect,FALSE);GetDlgItem(IDC_BTN_GAME_TIPS)-EnableWindow(FALSE);GetDlgItem(IDC_BTN_GAME_STOP)-EnableWindow(FALSE);GetDlgItem(IDC_BTN_GAME_REARRANGE)-EnableWindow(FALSE);GetDlgItem(IDC_BTN_GAME_START)-EnableWindow(TRUE);CString m_present;m_present.Format(_T(%4.0f%),(float)npos/(float)3.0);GetDlgItem(IDC_STATIC_TIME)-SetWindowTe*t(m_present);CDialogE*:OnTimer(nIDEvent);当用户点击游戏按钮时,进度条开场计时。实现代码如下:voidCGameDlg:OnClickedButtonStart()/开场游戏按钮 m_gameControl.StartGame();/开场游戏 UpDateMap();/更新地图 InvalidateRect(rect,FALSE);/更新游戏区域 GetDlgItem(IDC_BUTTON_START)-EnableWindow(FALSE);/让开场按钮变为灰色,开场游戏后不能再点击该按钮 GetDlgItem(IDC_BUTTON_PAUSE)-EnableWindow(TRUE);/开场游戏后将暂停游戏按钮设置为可点击状态 IsPlaying = true;/游戏标示设置为true m_bGamePause = false;/暂停游戏标示设置为false/启动定时器this-SetTimer(PLAY_TIMER_ID, 1000, NULL);3. 测试用例设计l 先从网上下载一*图标图片和几*BMP图像。l 先设计出游戏主界面,并且调整好相应的参数,并且加载游戏图标和游戏主界面背景。l 插入一个游戏对话框用来进展游戏,并且添加相应是事件,实现相应的功能。l 自己当一次游戏玩家,自己分别玩这个游戏的三个模式,看是否可以正常运行,运行过程是否正确,观察游戏是否按照想象中的那样运行。三、主要仪器设备及耗材l 安装了Windows *P或Windows 7或其它版本的Windows操作系统的PC机1台。l PC机系统上安装了Microsoft Visual Studio 2010开发环境。第二局部:实验过程和结果可加页一、 实现说明在Microsoft Visual Studio 2010集成开发环境中新建一个Win32控制台应用程序工程LLK。在LLK中新建三组相关文件。第一组是实现绘图相关操作的头文件GameDlg.h和原程序文件GameDlg.cpp。第二组是实现消子功能的头文件CGameLogic.h和源程序文件CGameLogic.cpp。第三组是实现游戏控制功能的头文件CGameControl.h和源文件CGameControl.cpp。同时新建一个global.h文件来存放Verte*构造体来存放图片的相关信息。二、 调试说明调试手段、过程及结果分析调试内容为编写程序的语法的正确性与否,程序逻辑的正确性与否。调试的主要手段是,设置断点,然后启动调试。例如在编写GameDlg.cpp的时候出现了图片是奇数的情况,但是通过设置断点并且点击调试后终于发现问题,经过修改后,编译成功。再如,在编写CHelpDialog类的时候,无法加载出背景图片,在屡次都找不出错误的情况下通过设置断点点击调试,终于找出问题所在,最终问题得以解决。三、 软件测试测试效果.界面、综合分析和结论1 测试效果.界面图1:主界面图2:根本模式界面图3:消子界面图4:重排界面图5:提示界面图6:获胜界面2综合分析和结论通过对位图的存储和对位图进展随机抽取就能够出现如图片所示的界面,并且通过对图片的设置就能到达消子的效果。能实验连连看实验的根本功能,绘制主界面地图,游戏界面地图,生成元素图片,元素图片的消除,连线的显示,计时,重排,提示等功能都能实现。实验的目的根本到达,根本完成了一个连连看的游戏。第三局部:实验小结、收获与体会这是我第一次编写工程开发程序,因为是第一次编写,所以在编写的过程中觉得很吃力,并且在这次实验中,很多函数以类都没有接触过,不知道它们的功能,所以需要花费很多时间去思考、构思,虽然在编写的过程中遇到了很多问题,但是通过不断的调试,以及跟同学一起探讨,很多问题也都被解决了。通过这次实验真的收获很多,同时也在一定程度上提高了我的编程能力,这次实验经历的时间很长,也消耗了自己很长的时间,不过最后实现了连连看游戏,自己感觉还是很棒的在这途中了解了MFC框架,包括MFC Dialog应用程序和GDI编程,了解线性构造,数组和栈操作,了解了图的数据构造和应用,和存储构造和邻接矩阵这种构造,了解企业软件开发的过程,应用迭代开发思路进展工程开发。虽然最后编写出来的连连看游戏还不是很完善,但是我会继续完善,不断修改。. z.
展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 压缩资料 > 基础医学


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!