五子棋游戏

一、整体思路

1、目的:通过五子棋,掌握面向对象的思想,这是我们的目的。提升分析问题、解决问题的能力,在做项目之前要有一个系统的思路,第一步干什么,第二步干什么……

2、思路:拿到这个问题,我们首先要设计一个类(CWuZiQi),设计一个类首先要想到它有哪些成员变量,有哪些属性。最核心的一个成员变量是棋盘(用二维数组m_QP[19][19]表示,数组是该程序的核心)。用0表示棋盘上没有棋子,用1表示黑子,2表示白子。我们还需要行(m_H)、列(m_L),以及当前棋子的颜色(m_Color)。

3、核心的三个函数:一个Draw函数;一个下棋(XiaQi)函数,下棋函数在按下鼠标时调用(传过来一个点的坐标);一个判断输赢(PanDuan)的函数。

二、最终实现效果图

三、实现步骤(前期)

1、新建一个MFC单文档应用程序,如下图所示。


2、设计一个类(CWuZiQi),添加一些成员变量并初始化,如下图所示。



3、先从简单的入手,把棋盘画出来。为了让界面更加美观,我们还可以画棋盘的背景(放大后整个屏幕的背景以及棋盘游戏区域背景)以及棋盘上面的九个星位,如下图所示。

①画棋盘背景

画棋盘背景代码如下:

//画屏幕背景和棋盘背景
void CWuZiQi::DrawBackground(CDC *pDC)
{CBrush brush1,*pOldBrush1;brush1.CreateSolidBrush(RGB(255,222,173));pOldBrush1 = pDC->SelectObject(&brush1);pDC->Rectangle(0,0,1920,960); //整个屏幕大小brush1.DeleteObject();pDC->SelectObject(pOldBrush1);
//==============================================int x,y,r;x = ydx;y = ydy;r = 18 * lenbl;CBrush brush2,*pOldBrush2;brush2.CreateSolidBrush(RGB(244,164,96));pOldBrush2 = pDC->SelectObject(&brush2);pDC->Rectangle(x,y,x + r,y + r); //棋盘大小brush2.DeleteObject();pDC->SelectObject(pOldBrush2);}

②画棋盘九个星位

画棋盘九个星位代码如下:

//画棋盘上的九个星位
void CWuZiQi::DrawXingWei(CDC *pDC)
{int x,y,r; for (int i = 4; i < 19; i+=5){for (int j = 4; j < 19; j+=5){x = ydx + i * lenbl;y = ydy + j * lenbl;r = lenbl/8;CBrush brush,*pOldBrush;brush.CreateSolidBrush(RGB(0,0,0)); //画星位pOldBrush = pDC->SelectObject(&brush);pDC->Ellipse(x - r, y - r, x + r, y + r);brush.DeleteObject();pDC->SelectObject(pOldBrush);}}
}

③画棋盘

画棋盘代码如下:

//画棋盘
void CWuZiQi::DrawQiPan(CDC *pDC)
{DrawBackground(pDC); //调用背景要放在画棋盘前面,若放在后面棋盘会被覆盖int x,y;for (int i = 0; i < 19; i++){x = ydx;y =  ydy + i * lenbl;pDC->MoveTo(x,y);x += 18 * lenbl;pDC->LineTo(x,y); //画行数x = ydx + i * lenbl;y = ydy;pDC->MoveTo(x,y);x += 18 * lenbl;pDC->LineTo(x,y); //画列数}DrawXingWei(pDC); //调用画的九个星位}

4、紧接着就是画棋子喽,用黑色画刷画黑子,白色画刷画白子,如下图所示。

画棋子代码如下:

void CWuZiQi::DrawQiZi(CDC *pDC)
{int i,j; int x,y;int r = lenbl/3;//棋子半径for (i = 0; i < 19; i++){for (j = 0; j < 19; j++){if (m_Qp[i][j] != 0) //如果棋盘上有子{if (m_Qp[i][j] == 1) //并且是黑子{CBrush brush,*pOldBrush;brush.CreateSolidBrush(RGB(0,0,0)); //画黑子pOldBrush = pDC->SelectObject(&brush);x = ydx + i * lenbl;y = ydy + j * lenbl;pDC->Ellipse(x - r, y - r, x + r, y + r);brush.DeleteObject();pDC->SelectObject(pOldBrush);}else if (m_Qp[i][j] == 2) //并且是白子{CBrush brush,*pOldBrush;brush.CreateSolidBrush(RGB(255,255,255)); //画白子pOldBrush = pDC->SelectObject(&brush);x = ydx + i * lenbl;y = ydy + j * lenbl;pDC->Ellipse(x - r, y - r, x + r, y + r);brush.DeleteObject();pDC->SelectObject(pOldBrush);}}}}}

5、再添加一个成员函数Draw(CDC *pDC),调用上面画好的棋盘、棋子,如下图所示。

调用代码如下:

void CWuZiQi::Draw(CDC *pDC)
{DrawQiPan(pDC);DrawQiZi(pDC);
}

6、步步为营,我们可以先在CGobangGameView里将#include “WuZiQi.h”头文件嵌入进来,并引入成员变量,如下图所示。


7、编译运行就能看见前期的效果了,由于还没有添加鼠标响应函数,所以棋子暂时没法显示。如下图所示。

四、实现步骤(中期)

中期主要就是两个工作,一个下棋函数,一个判断函数。

1、添加下棋成员函数,并编写代码(下棋函数在按下鼠标时调用(传过来一个点的坐标)),如下图所示。

下棋代码:

void CWuZiQi::XiaQi(CPoint pt)
{   //确定下棋边界if (pt.x > (ydx - lenbl/3) && pt.x < (ydx + 18 * lenbl + (lenbl/3)) &&\pt.y > (ydy - lenbl/3) && pt.y < (ydy + 18 * lenbl + (lenbl/3)))//注:lenbl/3是棋子半径,当棋子边缘碰到棋盘线时,也默认在棋盘内。{m_H = (pt.x - ydx + lenbl/4)/lenbl; //用当前点击位置减去原点距离,加上1/4小格的结果,整除小方格,确定在哪一行m_L = (pt.y - ydy + lenbl/4)/lenbl; //获取落子位置}if (m_Qp[m_H][m_L] == 0 && m_Color == 1) //落子位置没有棋子,并且是黑子下{m_Qp[m_H][m_L] = 1; //将当前点击的位置设置为黑子PanDuan(); //判断添加棋子后是否有五子if (m_Qp[m_H][m_L] == 1) //如果当前点击位置显示的是黑子,即黑子刚刚下过{m_Color = 2; //立即换白子下棋}else if (m_Qp[m_H][m_L] == 2) //如果当前点击位置显示的是白子,即白子刚刚下过{m_Color = 1; //立即换黑子下棋}}else if (m_Qp[m_H][m_L] == 0 && m_Color == 2) //落子位置没有棋子,并且是白子下{m_Qp[m_H][m_L] = 2; //将当前点击的位置设置为白子PanDuan(); //判断添加棋子后是否有五子if (m_Qp[m_H][m_L] == 1) //如果当前点击位置显示的是黑子,即黑子刚刚下过{m_Color = 2; //立即换白子下棋}else if (m_Qp[m_H][m_L] == 2) //如果当前点击位置显示的是白子,即白子刚刚下过{m_Color = 1; //立即换黑子下棋}}
}

2、添加判断函数,并编写代码,如下图所示。

判断代码:

void CWuZiQi::PanDuan()
{int i; //用来循环遍历的int left = 0,right = 0; //左右下棋for (i = 1; i <= 4; i++){if (m_Qp[m_H][m_L - i] == m_Color) //以(m_H,m_L)为中心,向左找,注意是列在减小,而不是行!left++;elsebreak; //碰到一个不是当前颜色的就停止}for (i = 1; i <= 4; i++){if(m_Qp[m_H][m_L + i] == m_Color) //以(m_H,m_L)为中心,向右找,注意是列在增大,而不是行!right++;elsebreak;}
//=================================================================================================================int up = 0,down = 0; //上下下棋for (i = 1; i <= 4; i++){if (m_Qp[m_H - i][m_L] == m_Color) //以(m_H,m_L)为中心,向上找,注意是行在减小,而不是列!(竖直向下为正)up++;elsebreak; //碰到一个不是当前颜色的就停止}for (i = 1; i <= 4; i++){if(m_Qp[m_H + i][m_L] == m_Color) //以(m_H,m_L)为中心,向下找,注意是行在增大,而不是列!down++;elsebreak;}
//=================================================================================================================int leftup = 0,rightdown = 0; //左上、右下,“\”下棋for (i = 1; i <= 4; i++){if (m_Qp[m_H - i][m_L - i] == m_Color) //以(m_H,m_L)为中心,向左上找,行列均在减小leftup++;elsebreak; //碰到一个不是当前颜色的就停止}for (i = 1; i <= 4; i++){if(m_Qp[m_H + i][m_L + i] == m_Color) //以(m_H,m_L)为中心,向右下找,行列均在增大rightdown++;elsebreak;}
//=================================================================================================================int leftdown = 0,rightup = 0; //左下、右上,“/”下棋for (i = 1; i <= 4; i++){if (m_Qp[m_H + i][m_L - i] == m_Color) //以(m_H,m_L)为中心,向左下找,行在增大,列在减小leftdown++;elsebreak; //碰到一个不是当前颜色的就停止}for (i = 1; i <= 4; i++){if(m_Qp[m_H - i][m_L + i] == m_Color) //以(m_H,m_L)为中心,向右上找,行在减小,列在增大rightup++;elsebreak;}
//=================================================================================================================if (left + right >= 4 || up + down >= 4 || leftup + rightdown >= 4 || leftdown + rightup >= 4){if(m_Color == 1)AfxMessageBox("黑棋获胜!");if(m_Color == 2)AfxMessageBox("白棋获胜!");}
}

五、实现步骤(后期)

1、在CGobangGameView里添加WM_LBUTTONDOWN
句柄,实现下棋时的消息响应,如下图所示。


代码如下:

void CGobangGameView::OnLButtonDown(UINT nFlags, CPoint point)
{// TODO: Add your message handler code here and/or call defaultWZQ.XiaQi(point); //下棋响应Invalidate(TRUE);CView::OnLButtonDown(nFlags, point);
}

2、为了更方便的显示当前是谁正在下棋,我们还可以定义两个鼠标(黑、白),若是黑子正在下,则显示黑棋鼠标;若是白子正在下,则显示白棋鼠标。如下图所示。


3、在CGobangGameView里添加WM_SETCURSOR
句柄,实现下棋时的消息响应,如下图所示。


4、在CGobangGameView里定义黑白鼠标的成员变量,并在构造函数里加载刚刚画的黑白棋子图像,如下图所示。


代码如下:

BOOL CGobangGameView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{// TODO: Add your message handler code here and/or call defaultif (nHitTest == HTCLIENT){//黑子下,显示黑棋鼠标if(WZQ.m_Color == 1)SetCursor(m_csrblack);//白子下,显示白棋鼠标elseSetCursor(m_csrwhite);return 1;}return CView::OnSetCursor(pWnd, nHitTest, message);
}

六、运行结果

七、总结
本设计基本实现了一个简单的人人对战五子棋游戏,整体设计难度偏小,对刚刚接触MFC的初学者来说是很好的一篇参考素材。
通过该游戏的设计,对面向对象的程序设计思想有了更加深刻的认识,也渐渐明白在做项目之前形成系统思路的重要性。
本文最满意的地方是对成员变量的巧妙运用,只需在构造函数里改变原点坐标位置(ydx,ydy)和棋盘上每个小方格的大小比例(lenbl)就能改变与之相关的内容,比如棋盘大小,游戏边界,棋子大小,游戏背景大小,等等,更加方便了程序的后期运行和维护。

VC6.0 MFC 单文档 五子棋游戏 基础入门相关推荐

  1. VC6.0 MFC 单文档 机器人巡检

    机器人巡检 一.整体框架 主要包括三个类:场景类(CChangJing):机器人类(小车(CCar).无人机(CWuRenJi)):煤气泄露类(CMeiQiXieLou). 二.场景类 目标主要是数据 ...

  2. OCC-7.6.0 + MFC单文档应用入门教程

    OCC-7.6.0 + MFC单文档应用 入门教程 磨刀不误砍柴工,如果你对MFC没任何基础,请先读这篇MFC的入门基础,它会降低你对这篇文章的恐惧感 开发环境说明 win7+ opencascade ...

  3. 从0开始创建一个MFC单文档工程

    MFC单文档快速入门教程 开发环境 win7+vs2019 如何创建一个新的MFC单文档项目 如何创建菜单添加点击事件 创建菜单我的->测试的菜单 修改测试的菜单ID为ID_MY_TEST如下 ...

  4. MFC单文档框架编程(二): SDI框架下的消息处理

    MFC单文档框架编程(一) ...................................................................................... ...

  5. VC++ MFC单文档应用程序SDI下调用glGenBuffersARB(1, pbo)方法编译通过但执行时出错原因分析及解决办法:glewInit()初始化的错误...

    1.问题症状 在VC++环境下,利用MFC单文档应用程序SDI下开发OpenGL程序,当调用glGenBuffersARB(1, &pbo)方法编译通过但执行时出错,出错代码如下: OpenG ...

  6. 【数字图像处理】 二.MFC单文档分割窗口显示图片

    本文是讲述<数字图像处理>系列文章,继上篇讲述BMP格式图片和显示后,该篇讲述如何对单文档进行分割.主要是采用CSplitterWnd静态分割窗口显示图片等相关知识.本文主要结合自己的课程 ...

  7. OpenGL MFC单文档 实现轨迹球

    OpenGL MFC单文档 实现轨迹球 前言:我是一个怀揣着伟大梦想的普通男生!结果就是,一有时间就幻想着自己的伟大梦想,忘了自己下一步该迈出左脚还是右脚.这不,只顾做梦了,时光可不管我,独自一个人走 ...

  8. MFC单文档之给主窗口添加背景图片

    MFC单文档之给主窗口添加背景图片 1.导入图片 选择一个bmp格式的图片,将其导入到res文件夹中,然后工程资源目录下导入此图,注意格式一定要确定是百分百bmp格式的,不然报错,有的图片很坑是假bm ...

  9. 用MFC单文档改写ARToolKit5.4的例子simpleLite

    RToolkit5.4自带的示例是控制台程序,用MFC单文档改写过程如下: 1.开发环境 Win10,VS2017,ARToolkit5.4 2.新建MFC单文档程序Test 在类向导中,为CTest ...

最新文章

  1. pc端汽车obd软件下载?_常用的ERP软件电脑端下载
  2. 编程珠玑第二章习题答案
  3. 装了mysql但是服务里没有反应_Mysql安装后在服务里找不到和服务启动不起来的解决方法...
  4. 深入浅出python机器学习_4.3.1_岭回归的原理 4.3.2_岭回归的参数调节
  5. 【数据结构与算法】之深入解析“寻找旋转排序数组中的最小值II”的求解思路与算法示例
  6. python的turtle库是另外下载嘛吗_python—turtle库的基本介绍
  7. postgresql grant权限解释
  8. C++基本控制类型及流程语句详解
  9. 试题5 算法训练 猴子吃包子
  10. Win7X64位Seleniume+Eclipse+Pydev环境搭建
  11. python控制风扇_如何使用Python在raspberrypi3上使用GPIO控制风扇?
  12. dstwo linux 模拟器,dstwo gba 模拟器-TempGBA下载V1.44 最新版-西西游戏下载
  13. AUTOCAD——多段线命令
  14. 同步AOKP源码的方法
  15. 苹果手机软件闪退怎么解决_《NBA2K21》闪退怎么办 闪退异常问题解决方法
  16. 循环 计算机英语,计算机英语词汇解释
  17. 如何实现有效的项目进度控制
  18. 实时热力图_原来微信按下这个键,就能轻松知道对方的实时位置,看完涨知识了...
  19. [CTSC2016]时空旅行
  20. Java ScriptEngineManager

热门文章

  1. android8.1系统连接不上BLE蓝牙设备问题解决
  2. 运营型CRM系统(运营型客户关系管理)只是针对于运营的吗?
  3. 3d游戏计算机怎么配置要求吗,游戏设计专业需要怎样的电脑配置?
  4. uid vfx_亚当–实时短片中的VFX
  5. 中国汽车制造行业市场供需与战略研究报告
  6. 小电流接地选线(一)
  7. 徐汇区企业技术中心认定条件及申报流程
  8. Troubleshut# 错误 C2061 语法错误: 标识符“XXXX”
  9. 任务栏 Adobe Acrobat DC / Adobe Reader 图标出错、异常、不显示(Windows下)
  10. 李忠汇编语言-初学-第五天