这是一个中国象棋的简单范例。
程序虽然简单
源代码在线查看: 请看这个说明.txt
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
// 嗨!我是王晓钰。
// 我的E-mail是:XiaoYu.wang@263.net 有问题可以发邮件或在网站上留言
// 欢迎你访问我的个人主页:“笑语小园”http://xiaoyu.2699.comn
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
// 二○○○年七月
// 让我们继续看我的程序。
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
这是西安交通大学电气学院的一个完整例子。附上可供参考。
这是一个中国象棋的简单范例。
程序虽然简单,但是能展示MFC的基本思想。
要求:在程序窗口客户区显示中国象棋棋盘和棋子,以及轮哪方行棋的提示。
用户可使用鼠标左键选择要移动的棋子以及移到何处。
不能将棋子移到已有己方棋子的位置,或移出棋盘。
一方移动棋子后自动提示该对方行棋。
后面是课本上的一些分析:
//%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
//%%祝你调试顺利
// 我的E-mail是:XiaoYu.wang@263.net 有问题可以发邮件或在网站上留言
//%%2000年7月,王晓钰
//%%¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
[例10-4] 可供两人在计算机上对弈的中国象棋程序。
说 明:建立项目的方法见9.8:“用Visual C++集成开发环境开发Win32应用程序”。
程 序:(见附录3:“可供两人对弈的中国象棋程序”)
输入输出:在程序窗口客户区显示中国象棋棋盘和棋子,以及轮哪方行棋的提示(图10-2)。用户可使用鼠标左键选择要移动的棋子以及移到何处。不能将棋子移到已有己方棋子的位置,或移出棋盘。一方移动棋子后自动提示该对方行棋。
分 析:尽管这这只是一个相当粗略的游戏程序框架(例如程序中没有反应各棋子的行棋规则,更不用说利用人工智能,将机器作为一方与人对弈了),但程序长度已达四、五百行。实际上,真正的应用程序规模总是很大。通过仔细阅读和分析本程序,以及对本程序的进一步完善(如增加对各种棋子行棋规则的判断等),可大大提高编写程序的能力。
在程序中,首先声明了一个棋盘类和一个棋子类,用于存放棋盘类和棋子类对象的有关属性。
棋盘类的数据成员包括棋盘的大小、位置以及棋盘格的宽度。棋盘类的成员函数是棋盘类的对外接口,包括棋盘类的构造函数(用于初始化棋盘参数)和显示棋盘。在显示棋盘成员函数ShowPlate()中,又调用了一个用于画兵、炮位标志的DrawConer()函数。ShowPlate()函数有一个CDC类的指针参数,在框架窗口类的OnPaint()成员函数中可以看到,该参数的实参为CPaintDC类的设备环境。另一个成员函数GetPosition()给出了棋盘上某交叉点的实际坐标(用于画棋子或判断鼠标是否指向某交叉点)。
棋子类的数据成员包括棋子的位置、名称、颜色、是否被吃掉(不显示)、是否被选择(被选择的棋子要变颜色,以利识别)等属性。其成员函数包括构造函数(用于设置棋子初值)和显示棋子、将棋子移到棋盘某交叉点、查看棋子的各种属性的函数。其中大部分成员函数比较简单,所以使用了内联函数形式。注意在显示棋子函数中,只显示未被吃掉的棋子,且被选择的棋子颜色有变化(由黄色变为灰色)。
框架窗口类用于实现具体的下棋过程。框架窗口类的数据成员包括一个棋盘对象和一个棋子对象的数组。棋子数组的前一半存放红方棋子,后一半存放黑方棋子。其他数据成员用于存放轮哪方行棋、是否选择了棋子等标志信息。
框架窗口类的构造函数调用InitGame()函数初始化棋局,主要是通过调用棋子类的构造函数来设置各个棋子。
OnPaint()函数根据棋盘的设置和各棋子的当前状况显示棋盘、棋子和提示信息。
消息响应函数OnLButtonDown()用于处理用户的走棋消息。实际上,走一步棋需要点两次鼠标左键,第一次用于选择要移动的棋子,第二次用于指出要将选定的棋子移向何处。因此,当用户按下鼠标左键时,首先要判断是否已选定了一枚棋子。如果是,则应移动该棋子,否则应选定鼠标指向的那枚棋子。
选定棋子的工作实际上是通过逐个检查己方的所有未被吃掉的棋子,看其是否在鼠标下。如果有一枚己方棋子被选中,则设置选中标志,并通知OnPaint()更新窗口客户区该棋子的区域(因为被选中的棋子要变为灰色)。
如果已选择了一枚棋子,则再次点击鼠标左键应该移动被选中的棋子。首先要确定该位置可以走棋(如非棋盘交叉点、棋盘外或已有己方棋子的对方均不能走棋),这是通过逐个检查棋盘上的每个交叉点实现的。如果该点可以走棋,则将选定的棋子移向该处。这包括修改棋子的位置参数(CStone::MoveTo)、分别通知OnPaint()更新棋子原来位置和新位置的图象、还原选择棋子标志检查是否吃了对方棋子等工作。如果吃了对方的“将”或“帅”,则宣布本局结束并重新摆好棋盘,进行下一局。
如果仅仅走一部棋或吃了对方其他棋子,则本方行棋结束,轮对方行棋。在程序中,这项工作包括改变轮谁行棋的标志和显示相应的提示信息。
单元上机练习题目