MFC课程设计———五子棋.doc_第1页
MFC课程设计———五子棋.doc_第2页
MFC课程设计———五子棋.doc_第3页
MFC课程设计———五子棋.doc_第4页
MFC课程设计———五子棋.doc_第5页
已阅读5页,还剩30页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Windows程序设计课程考核报告班 级: 学 号: 姓 名: 得 分: 2016年6月 25 日1.设计目的及要求31.1设计目的及内容31.2设计要求31.3软件、硬件环境32.课程设计步骤43. 课程设计内容153.1 概要设计153.1.1 程序总体框架描述153.1.2程序常用类声明163.2主要技术173.3系统设计结果 (界面截图、操作流程)174.设计总结194.1遇到的问题及如何解决194.2体会195.源代码201.设计目的及要求 1.1设计目的及内容描述 1. 了解Windows编程的基础知识,掌握MFC应用程序的基本知识;2. 基本掌握面向对象程序设计的基本思路和方法;3. 掌握用VC+开发应用程序的的一般步骤和方法;4. 能够利用所学的基本知识, 设计一个简单的五子棋游戏,具有以下功能:数据结构的设计;五子棋棋盘的绘制。两人下棋时,两人下棋算法的设计。两人下棋时,判断任一方获胜的算法的设计。1.2设计要求 用VS 2010进行编码,实现应用程序的功能。注重编码质量,代码要有适当的注释;提交设计报告一份(课程设计任务书、目录、主要的数据结构、设计的基本思路、设计的步骤及主要代码、心得体会、参考文献)。游戏规则: 首先可以在更多选项里面选择进行人人对战与人机对战,并可以在人机对战的功能框里选择难易程度。当棋子连成有五个时游戏结束。程序功能模块棋局的绘制、保存、和AI三大块1.3软件、硬件环境 软件:Windows 10操作系统,Microsoft Visual studio 2010 硬件:Inter(R) Core(TM) i5-4200H CPU 3.40GHz2.课程设计步骤 新建单文档程序Gobang_FiveChess 接着就是定义变量了,但是,由于这个游戏要添加的变量和函数太多了,我们要建一个新类。是否应该先添加应该类呢?最好是这样。因为新类将会涉及到变量。添加普通类CChessclass CChesspublic:CChess(void);CChess(void);void Init(CRectrect);void Draw(CDC*pDC); / 画棋局void SetPiecePos(CPointptCurrent);/ 设置当前棋子的位置 下棋函数void NewGame(); / 新游戏BOOL Regret();/ 悔棋void SetVSMode(enumVSModeemVSMode);/ 设置对战模式enumVSModevoid SetAIDepth(intemAIDepth); / 设置AI智能程度enumWinFlagGetWinFlag(); / 获取输赢状况CRect GetRectBoard(); / 获取棋盘区域private:enumChessColorm_iPositionPieceCOLUMNSROWS;/ 棋子的信息CChessDraw m_chessdraw; / 棋局绘制类CRectm_rcBoard; / 棋盘区域CPointm_ptCurrent; / 棋子当前位置enumWinFlag m_emWin; / 输赢状况enumVSMode m_emVSMode; / 对战模式 STC_REGRET m_stcLastPos; / 记录最近一次的下棋位置 BOOL m_bTurnBlack; / 是否轮到黑方下棋 int m_emAIDepth; / AI智能程度 为方便外部调用SetAIDepth(),所以设为了int类型BOOL IsWin(UINTuiCol,UINTuiRow,enumChessColor emChessColor); / 在第uiCol列第uiRow行,判断是否结束,若结束则返回TRUE BOOL GetBestPosByAI(UINT&uiCol,UINT&uiRow,enumChessColor emEnemyChessColor = BLACK); / 获取最好的下棋位置,机器都为白色;添加函数:构造函数:CChess:CChess(void) m_bTurnBlack = TRUE;m_emWin= FIGHTING;m_emVSMode = PERSON_VS_MACHINE; m_emAIDepth = AI_MIDDLE; m_ptCurrent= CPoint(-1,-1);/ 只要不在棋盘内的点都可以memset(m_iPositionPiece,0,sizeof(m_iPositionPiece); m_stcLastPos.iPieceNum = 0; m_stcLastPos.ptBlack = CPoint(0,0); m_stcLastPos.ptWhite = CPoint(0,0); m_stcLastPos.ptLastCurPoint = CPoint(-1,-1);画图函数:void CChess:Draw(CDC*pDC)CMyMemDCmemDC(pDC);m_chessdraw.SetDC(memDC);m_chessdraw.DrawBackground();m_chessdraw.DrawBoard();/ - 重画整个棋局 - if(FIGHTING= m_emWin)/ 没分胜负时才允许改变m_emWin的状态m_emWin= PEACE;for(inti = 0;i COLUMNS;i+)for(intj = 0;j ROWS;j+)if(NONE != m_iPositionPieceij)m_chessdraw.DrawPiece(i, j,BLACK= m_iPositionPieceij);elseif(PEACE = m_emWin)m_emWin= FIGHTING;/ 若有空位,则还可以继续,否则平局,即m_emWin= PEACE;m_chessdraw.DrawPieceCur(m_ptCurrent.x, m_ptCurrent.y);/ 标记当前棋子 下棋函数:voidCChess:SetPiecePos(CPointptCurrent)if(FIGHTING!= m_emWin) return;/ 没分胜负时才允许改变m_ptCurrent的状态 UINTuiPosX,uiPosY;if(! m_chessdraw.GetCoordinateWithPoint(ptCurrent,&uiPosX, &uiPosY)return;/ 不在棋盘内的位置不做处理if(NONE!= m_iPositionPieceuiPosXuiPosY)return;/ 已有棋子的位置不做处理 for(int i = 0; i 0) & (FIGHTING = m_emWin) / 如已分出胜负,则不再允许悔棋 m_stcLastPos.iPieceNum = 0; /只允许悔一步 m_ptCurrent = m_stcLastPos.ptLastCurPoint; if(PERSON_VS_MACHINE = m_emVSMode) m_iPositionPiecem_stcLastPos.ptBlack.xm_stcLastPos.ptBlack.y = NONE; m_iPositionPiecem_stcLastPos.ptWhite.xm_stcLastPos.ptWhite.y = NONE; if(PERSON_VS_PERSON = m_emVSMode) if(! m_bTurnBlack) m_iPositionPiecem_stcLastPos.ptBlack.xm_stcLastPos.ptBlack.y = NONE; else m_iPositionPiecem_stcLastPos.ptWhite.xm_stcLastPos.ptWhite.y = NONE; m_bTurnBlack = ! m_bTurnBlack; return TRUE; return FALSE;设置对战模式:voidCChess:SetVSMode(enumVSModeemVSMode) m_emVSMode = emVSMode;voidCChess:SetAIDepth(int emAIDepth) m_emAIDepth = emAIDepth;3. 课程设计内容 3.1 概要设计 游戏的操作方面主要以鼠标点击为主,鼠标点击方格里面进行落子操作。选择人人对战,人机对战(选择对战难度),五子连棋时就判断白方或者黑方胜利。3.1.1 程序总体框架描述 1.创建程序2.棋盘功能构建3.游戏构架组成4.游戏过程以及结束设定3.1.2本项目主要有棋局绘制、棋局功能、机器AI三个类,主要源码文件如下图 3.2主要技术 1.界面的设置2.下棋处理函数;3.视图框架设置;4.机器AI算法。5.功能的设置。3.3系统设计结果 (界面截图、操作流程)1.界面截图:此为困难级别,白色为机器方。 操作流程图界面更多选项选择开始人人人机结束难度4.设计总结4.1遇到的问题及如何解决随着五子棋游戏的开发完成,本游戏中预期的主要功能也基本实现。本系统以Visual studio 2010作为前台开发工具,Visual studio 2010以简单、易用等优点成为开发本系统的首选工具。本论文阐述了五子棋游戏的分析与设计的全过程,并在论文中相应的位置插入了图片、流程图以及一些具有技巧性的程序代码,更加清晰的描述了该游戏是如何实现的。五子棋游戏是一款益智类游戏,该游戏与那些网络游戏和3D游戏相比,它有编写简单容易上手等特点,非常适合人们在完成工作的时候适当的娱乐要求。这些小游戏大都是以益智和娱乐为目的,不仅给紧张工作的人们以放松,还可以让人们的大脑得到开发。由于我学习Visual studio 2010和MFC的时间比较短,其中的很多知识还没有了解和掌握,当然出现了很多错误,在设计过程中出现鼠标不响应操作的现象,这是因为定义鼠标函数时出现了错误;在设计过程中对位图的设置不够了解,总是不能调用位图,通过百度,才知道缺少了一部分代码;对于分号、引号的符号出现了不少的错误,主要是中英文切换时没注意,导致编译出错;完成程序之后,对程序进行编译,系统总是提示链接出错,经过仔细检查没有找到语句或定义错误,后来发现是电脑问题,我在任务管理器中结束wkh.exe。再次链接,错误就消除了。4.2体会在五子棋游戏中有些功能还不够完善,例如在五子棋游戏中不能实现游戏的保存和声音的添加。希望在以后的工作和学习中不断的充实自己的知识结构,把扫雷游戏的功能进一步完善,使它成为一个更具有实用价值的游戏软件,同时也恳请老师给予批评指正。5.源代码CChess:CChess(void) m_bTurnBlack = TRUE;m_emWin= FIGHTING;m_emVSMode = PERSON_VS_MACHINE; m_emAIDepth = AI_MIDDLE; m_ptCurrent= CPoint(-1,-1);/ 只要不在棋盘内的点都可以memset(m_iPositionPiece,0,sizeof(m_iPositionPiece); m_stcLastPos.iPieceNum = 0; m_stcLastPos.ptBlack = CPoint(0,0); m_stcLastPos.ptWhite = CPoint(0,0); m_stcLastPos.ptLastCurPoint = CPoint(-1,-1);CChess:CChess(void) NewGame();void CChess:NewGame() m_bTurnBlack = TRUE;m_emWin= FIGHTING;m_ptCurrent= CPoint(-1,-1);memset(m_iPositionPiece,0,sizeof(m_iPositionPiece); m_stcLastPos.iPieceNum = 0; m_stcLastPos.ptBlack = CPoint(0,0); m_stcLastPos.ptWhite = CPoint(0,0); m_stcLastPos.ptLastCurPoint = CPoint(-1,-1); if(MACHINE_VS_MACHINE = m_emVSMode) CPoint ptFirst; srand(time(NULL); ptFirst.x= rand()%COLUMNS; ptFirst.y= rand()%ROWS; m_chessdraw.GetPointWithCoordinate(ptFirst, ptFirst.x, ptFirst.y); SetPiecePos(ptFirst); void CChess:Init(CRectrect)m_chessdraw.InitBoard(rect, COLUMNS, ROWS, rect.Height() / ROWS, rect.Height() / ROWS / 2 - 2);m_rcBoard= m_chessdraw.GetRectBoard();CRectCChess:GetRectBoard()returnm_rcBoard;void CChess:Draw(CDC*pDC)CMyMemDCmemDC(pDC);m_chessdraw.SetDC(memDC);m_chessdraw.DrawBackground();m_chessdraw.DrawBoard();/ - 重画整个棋局 - if(FIGHTING= m_emWin)/ 没分胜负时才允许改变m_emWin的状态m_emWin= PEACE;for(inti = 0;i COLUMNS;i+)for(intj = 0;j ROWS;j+)if(NONE != m_iPositionPieceij)m_chessdraw.DrawPiece(i, j,BLACK= m_iPositionPieceij);elseif(PEACE = m_emWin)m_emWin= FIGHTING;/ 若有空位,则还可以继续,否则平局,即m_emWin= PEACE;m_chessdraw.DrawPieceCur(m_ptCurrent.x, m_ptCurrent.y);/ 标记当前棋子 voidCChess:SetPiecePos(CPointptCurrent)if(FIGHTING!= m_emWin) return;/ 没分胜负时才允许改变m_ptCurrent的状态 UINTuiPosX,uiPosY;if(! m_chessdraw.GetCoordinateWithPoint(ptCurrent,&uiPosX, &uiPosY)return;/ 不在棋盘内的位置不做处理if(NONE!= m_iPositionPieceuiPosXuiPosY)return;/ 已有棋子的位置不做处理 for(int i = 0; i 2 ; i+) m_iPositionPieceuiPosXuiPosY= m_bTurnBlack ? BLACK : WHITE; / - 判断输赢 - if(IsWin(uiPosX,uiPosY,m_iPositionPieceuiPosXuiPosY) m_ptCurrent = CPoint(uiPosX, uiPosY); return; / 已分出胜负 / - 记录上一次的棋子位置 - if(PERSON_VS_PERSON = m_emVSMode) | (m_bTurnBlack & (PERSON_VS_MACHINE = m_emVSMode) m_stcLastPos.ptLastCurPoint = m_ptCurrent; if(m_bTurnBlack) m_stcLastPos.ptBlack = CPoint(uiPosX, uiPosY); else m_stcLastPos.ptWhite = CPoint(uiPosX, uiPosY); m_stcLastPos.iPieceNum+; m_ptCurrent = CPoint(uiPosX, uiPosY); / - 轮到白方下棋 - m_bTurnBlack = ! m_bTurnBlack; if(! m_bTurnBlack & (PERSON_VS_MACHINE = m_emVSMode) if(! GetBestPosByAI(uiPosX, uiPosY, (! m_bTurnBlack) ? BLACK : WHITE) return; / 已分出胜负 if(PERSON_VS_PERSON = m_emVSMode) break; / 如果是人人对战,则退出循环 enumWinFlagCChess:GetWinFlag()returnm_emWin;BOOLCChess:IsWin(UINTuiCol,UINTuiRow,enumChessColor emChessColor) intiSameColorMAXCREASE; GetSameColor(uiCol, uiRow, emChessColor, iSameColor, m_iPositionPiece); for(intm = 0; m MAXCREASE) m_emWin= (BLACK = emChessColor) ? BLACK_WIN : WHITE_WIN; returnTRUE; returnFALSE;BOOLCChess:Regret() if(m_stcLastPos.iPieceNum 0) & (FIGHTING = m_emWin) / 如已分出胜负,则不再允许悔棋 m_stcLastPos.iPieceNum = 0; /只允许悔一步 m_ptCurrent = m_stcLastPos.ptLastCurPoint; if(PERSON_VS_MACHINE = m_emVSMode) m_iPositionPiecem_stcLastPos.ptBlack.xm_stcLastPos.ptBlack.y = NONE; m_iPositionPiecem_stcLastPos.ptWhite.xm_stcLastPos.ptWhite.y = NONE; if(PERSON_VS_PERSON = m_emVSMode) if(! m_bTurnBlack) m_iPositionPiecem_stcLastPos.ptBlack.xm_stcLastPos.ptBlack.y = NONE; else m_iPositionPiecem_stcLastPos.ptWhite.xm_stcLastPos.ptWhite.y = NONE; m_bTurnBlack = ! m_bTurnBlack; return TRUE; return FALSE;voidCChess:SetVSMode(enumVSModeemVSMode) m_emVSMode = emVSMode;voidCChess:SetAIDepth(int emAIDepth) m_emAIDepth = emAIDepth;BOOL CChess:GetBestPosByAI(UINT&uiCol,UINT&uiRow,enumChessColor emEnemyChessColor) POINT ptPosWhite, ptPosBlack = CPoint(uiCol, uiRow); BOOL bContinue = TRUE; switch(m_emAIDepth) case AI_FOOLISH: bContinue = :AIFoolish(ptPosWhite,ptPosBlack,emEnemyChessColor, m_iPositionPiece); break; case AI_PRIMARY: bContinue = :AIPrimary(ptPosWhite, m_iPositionPiece); break; case AI_MIDDLE: bContinue = :AIMiddle(ptPosWhite, m_iPositionPiece); break; case AI_HIGH: bContinue = :AIHigh(ptPosWhite, m_iPositionPiece); break; default: break; uiCol = ptPosWhite.x; uiRow= ptPosWhite.y; if(! bContinue) m_emWin= PEACE; return FALSE; return TRUE;CChessDraw:CChessDraw()m_pDC= NULL;m_rcBK.SetRectEmpty();m_rcBoard.SetRectEmpty();m_crBKBegin= RGB(255,232,166);m_crBKEnd= RGB(255,220,200);m_crBoard= RGB(0,0,0);m_uiPieceRadius= 0;m_uiBoardRows= 0;m_uiBoardCols= 0;m_uiBoardWidth= 0;CChessDraw:CChessDraw()/ 不能这么做,因为指向的是外部指针,不要对外部指针做任何更改/ m_pDC-DeleteDC();/m_pDC= NULL;voidCChessDraw:InitBoard(CRectrect, UINTuiRows, UINTuiCols, UINTuiBoardWidth, UINTuiPieceRadius)m_rcBK= rect;m_uiBoardRows= uiRows;m_uiBoardCols= uiCols;m_uiBoardWidth= uiBoardWidth;m_uiPieceRadius= uiPieceRadius;/ 计算棋盘区域m_rcBoard= m_rcBK;m_rcBoard.DeflateRect(CSize(20,20);/ 背景区域的左上点偏移(20,20)再画棋盘m_rcBoard.right= m_rcBoard.left + m_uiBoardWidth * (m_uiBoardCols - 1);m_rcBoard.bottom= m_rcBoard.top + m_uiBoardWidth * (m_uiBoardRows - 1);CRectCChessDraw:GetRectBoard()returnm_rcBoard;voidCChessDraw:SetDC(CDC*pDC) m_pDC= pDC;void CChessDraw:DrawBackground() if(! m_pDC) return; GradientFillRect(m_pDC,m_rcBK,m_crBKBegin,m_crBKEnd,TRUE);void CChessDraw:DrawBoard()if(! m_pDC)return;/ 画横线UINTptTop= m_rcBoard.top;for(UINT i= 0;i MoveTo(m_rcBoard.left, ptTop);m_pDC-LineTo(m_rcBoard.right,ptTop);ptTop+= m_uiBoardWidth;/ 画竖线UINTptLeft= m_rcBoard.left;for(UINT i= 0;i MoveTo(ptLeft, m_rcBoard.top);m_pDC-LineTo(ptLeft,m_rcBoard.bottom);ptLeft+= m_uiBoardWidth;/ 画天元等点DrawSpecialPoints();BOOL CChessDraw:DrawPiece(CPointpt,BOOLbBlack)if(! m_pDC| ! GetCoordinateWithPoint(pt)returnFALSE;CRectrc(pt - CSize(m_uiPieceRadius,m_uiPieceRadius),pt + CSize(m_uiPieceRadius,m_uiPieceRadius);CRgnrgn;rgn.CreateEllipticRgnIndirect(rc);m_pDC-SelectClipRgn(&rgn, RGN_AND);if(bBlack)FillGradientEx(m_pDC,rc,RGB(140,130,120),RGB(0,0,0),FALSE); / 画黑棋/GradientFillRect(m_pDC,rc,RGB(0,0,255),RGB(180,180,180),TRUE);/ 此函数有点问题(以这行代码运行后,可以看出来)elseFillGradientEx(m_pDC,rc,RGB(255,255,255),RGB(180,200,180),FALSE); / 画白棋m_pDC-SelectClipRgn(NULL);returnTRUE;BOOLCChessDraw:DrawPiece(UINTuiX,UINTuiY,BOOLbBlack)CPointpt;if(! m_pDC| ! GetPointWithCoordinate(pt, uiX, uiY)returnFALSE;CRectrc(pt - CSize(m_uiPieceRadius,m_uiPieceRadius),pt + CSize(m_uiPieceRadius,m_uiPieceRadius);CRgnrgn;rgn.CreateEllipticRgnIndirect(rc);m_pDC-SelectClipRgn(&rgn, RGN_AND);if(bBlack)FillGradientEx(m_pDC,rc,RGB(140,130,120),RGB(0,0,0),FALSE);elseFillGradientEx(m_pDC,rc,RGB(255,255,255),RGB(180,200,180),FALSE);m_pDC-SelectClipRgn(NULL);returnTRUE;void CChessDraw:DrawPieceCur(CPointpt)if(! m_pDC| ! GetCoordinateWithPoint(pt)return;CPenpenNew(PS_DASH, 1, RGB(255,0,0);CPen*penOld= m_pDC-SelectObject(&penNew);/intiSize= 5;intiSize= m_uiPieceRadius/3;/ 画横线m_pDC-MoveTo(pt.x-iSize, pt.y);m_pDC-LineTo(pt.x+iSize, pt.y);/ 画竖线m_pDC-MoveTo(pt.x,pt.y-iSize);m_pDC-LineTo(pt.x,pt.y+iSize);m_pDC-SelectObject(penOld);voidCChessDraw:DrawPieceCur(UINTuiX,UINTuiY)CPointpt;if(! m_pDC| ! GetPointWithCoordinate(pt, uiX, uiY)return;CPenpenNew(PS_DASH, 1, RGB(255,0,0);CPen*penOld= m_pDC-SelectObject(&penNew);intiSize= m_uiPieceRadius/2 - 1;/ 画横线m_pDC-MoveTo(pt.x-iSize, pt.y);m_pDC-LineTo(pt.x+iSize, pt.y);/ 画竖线m_pDC-MoveTo(pt.x,pt.y-iSize);m_pDC-LineTo(pt.x,pt.y+iSize);m_pDC-SelectObject(penOld);void CChessDraw:DrawSpecialPoints()if(! m_pDC)return;CRect rcTmp;CRect rc= m_rcBoard;COLORREFrgb = RGB(0,0,0);UINT uiSpecialRadius = m_uiPieceRadius/2 - 1;/ 天元等点的半径(默认为正方形,此值表示边长的一半)CSize szRadius(uiSpecialRadius,uiSpeci

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论