MFC制作五子棋
一、 结果展示:
二、 需求分析:
1) 五子棋游戏逻辑分析:
五子棋游戏规则简单易懂:棋盘大小为15*15;棋子分为黑白两色;若任意一方在“米字格”任意方向连成5子即为赢得胜利;
2) MFC程序功能分析:
2.1) 程序支持选择棋盘颜色,并且菜单项界面要随之发生更新;
2.2) 程序支持新建游戏、保存游戏、打开游戏;
2.3) 程序支持悔棋功能;
3) MFC界面分析:
3.1) Status Bar需要显示当前棋盘颜色以及提示下一步棋子的颜色;
3.2)Status Bar需要显示 Tool Bar按钮的帮助提示;
三、 代码设计:
1) 采用MFC中单文档 Document/View框架;其中,Document 子类(MyDVDocument)主要实现需求分析中的2.2以及管理游戏逻辑,并向View子类(MyDVView)提供界面更新的数据;
2) 游戏逻辑由Chess类、ChessManager类、ChessOperation类实现;Chess类对应棋子;ChessManager类负责管理整个游戏,是MyDVDocument类主要功能的底层实现;ChessOperation是自己实现的一个关于用户操作的链表类,主要支持悔棋操作;
3) 菜单由VS2017的资源编辑器编辑即可,并在MainFrame类中添加CToolbar类对象,在MainFrame的OnCreate函数里加载对应的资源文件;关于菜单项的相应事件主要在MyDVView里实现:菜单项界面更新就通过ON_UPDATE_COMMAND_UI消息映射完成;类图以及项目结构如下:
四、 知识点:
1) 游戏逻辑中主要是棋子的管理(ChessManager类),在判断游戏是否结束的函数里,我们需要分别检查“米”的三个方向,我们只需要以新增棋子为中心,检查其周围9个棋子,看是否连接成5子即可;
2) MyDVView类的一个主要功能是相应鼠标点击事件,并且将屏幕的坐标系转化为游戏中的逻辑坐标;为了方便统一,我们游戏中的棋盘对应一个二维数组,从上到下、从左到右依次对应屏幕坐标系的Y、X轴,通过一个简单的转换函数即可实现;
3) 要实现保存游戏进度,就要实现MyDVDoc类的OnNewDocument函数以及OnOpenDocument函数;在这两个函数里需要我们处理一下界面更新的问题,比如通知MyDVView更新界面等;那么游戏数据是怎样从磁盘文件加载到类(MyDVDoc类)成员中的呢?完成这一功能的函数是MyDVDoc类的Serialize函数,该函数负责游戏数据的保存与读取,而且我们并不需要手动调用该函数:当系统捕捉到新建、保存等菜单项被点击时,系统(MFC框架)在完成一系列工作后会自动调用该函数,而且在调用OnNewDocument之类的函数时已经完成该步骤,所以游戏数据已为最新,所以通知View更新界面即可;
4) 还有的一个知识点就是菜单项以及状态栏相关信息的更新;既然是更新,那么就涉及到什么时候更新?如何更新这一问题。菜单项的更新包括在前面打钩、是否可用等。我们点击菜单栏里的按钮后会弹出一系列菜单项,在这些菜单项弹出之前,系统会调用这组菜单项的界面更新函数,而这些函数是通过消息(ON_UPDATE_COMMAND_UI)映射实现同菜单项的关联。不但状态栏也是一样,只是状态栏里的Panel更新是在程序处于空闲(就是消息队列中没有任何消息的时候)由MFC框架调用;我们只需要在相应函数里写好如何更新即可。
更新
—————————————————————————
有朋友说我的项目bug太多,程序不通,需要调试,不建议下载源码。
我自己刚才重新下载了源码,遇到两个问题:一是我的VS没有安装MFC,需要安装,二是SDK版本不对,重定向项目即可解决。这是因为我重装电脑后下载的新的VS,旧版本的SDK找不到也是理所当然。
另外,我承认工程中有功能不完善,其主要是在:
1. 一方获胜后,没有添加重新开局功能——其实就是一个函数调用的问题,即开局菜单项对应的功能函数,这一问题也导致保存获胜局后,再次打开文件时,可以继续下棋的bug;
2. 对悔棋操作没有做允许检查,所以在没棋可悔的情况下会出现空指针的问题——这的确是代码中的bug,是我的疏忽,没考虑到没棋可悔时点击悔棋按钮的情况),但解决起来应该也不难——可以判断操作栈是否为空,如果为空就将菜单项disable即可;
这是我们Windows编程的作业,重点在于MFC机制的了解,包括文件保存、菜单更新、底部状态栏的更新等内容,五子棋游戏规则的实现虽然重要,但不是重点,所以当时也没有十分在意;
程序就不更啦,至于其他bug,有发现的朋友,欢迎可以评论区指出;至于源码,其实编程中最没用的东西就是源码了~链接还在放下面,有意者请移步,无意者略过即可。
下面放几张我测试的图,以证明我不是一个随便骗积分的人。