可供两人对弈的中国象棋程序

合集下载

象棋过关擂台赛规则

象棋过关擂台赛规则

象棋过关擂台赛规则
象棋过关擂台赛是一项考验棋手的擂台赛事,旨在比较不同棋手的象棋技能。

本项赛事组织分为初赛和决赛两部分,它们的流程如下:
初赛:
1、参赛选手:每支队伍由两位参赛选手组成,每位选手最多
可以参加五场比赛。

2、规则:比赛采用国际棋联规定的规则,比赛模式为交替进攻,每一场比赛由双方发起连续20步之内结束,最先将另一
方的王给将军者获得胜利。

3、比赛流程:比赛分为组内比赛和组间比赛,组内比赛前八名参赛选手进入组间比赛,在组间比赛阶段中,比赛结束后,以分数最高的选手为胜利者。

决赛:
1、参赛选手:决赛参赛选手由组内比赛中获得最高成绩者及
其队友组成,至少要有十支队伍参加决赛。

2、规则:比赛采用国际棋联规定的规则,比赛模式为双方同
时进攻,比赛结束后,谁的分数最高者获胜。

3、比赛流程:决赛由12场比赛组成,其中,每一场比赛以
双方必须同时完成的50步之内结束。

最终获胜者将获得该项
比赛的总冠军。

象棋过关擂台赛的规则旨在以安全的方式让参赛者较量技术,进而深入探讨象棋技能。

参赛者可以灵活运用棋谱,把握机会,
发挥才干,尽情展示自己的特长。

最后,希望参赛者在有趣和精彩的比赛中取得好成绩,赢得胜利,增强自信。

二王棋规则

二王棋规则

二王棋规则
二王棋是一种两人对弈的棋类游戏,又称“二鬼棋”,起源于中国。

以下是二王棋的规则:
1.棋盘:二王棋棋盘为7行7列的方格棋盘,其中红方在上方,黑方在下方。

2.棋子:每方各有两个“王”棋子和若干个“兵”棋子,其中“王”棋子可以在任何方向上移动,“兵”棋子只能直线前进。

3.走法:每方轮流走棋,“王”棋子可以在任何方向上移动一格,“兵”棋子只能向前直线前进一格。

4.攻击:棋子可以攻击对方棋子,攻击方式有两种:直接攻击和间接攻击。

直接攻击是指棋子直接落在对方棋子上,将其吃掉;间接攻击是指棋子绕过对方棋子落在对方棋子的后面,将其围死。

5.胜负:当一方的两个“王”被吃掉或无法行动时,游戏结束,对方获胜。

需要注意的是,由于二王棋规则相对简单,棋谱变化多样,因此需要玩家具备一定的棋艺和思考能力才能取得胜利。

java课程设计---中国象棋对弈系统

java课程设计---中国象棋对弈系统

目录摘要 (1)关键字 (1)正文 (2)1、程序设计说明 (2)1.1 程序的设计及实现 (2)1.1.1搜索引擎的实现(engine包) (2)1.1.2信息传输机制(message包) (3)1.1.3棋子(pieces包) (3)1.2 主控模块(main包) (3)2、运行结果 (5)3、设计体会 (6)附件 (7)程序代码 (7)参考文献资料 (41)1中国象棋对弈系统Java语言程序设计实验报告实验项目名称:中国象棋对弈系统作者姓名与单位:李非计算机101摘要:本文主要是运用java实现具有一定功能的中国象棋对弈系统软件,主要功能如下:a、象棋对弈:红方先走,然后黑方再走,红黑交替,直到一方获胜。

b、新游戏:任何时候可以重新开始一盘新的对弈。

c、悔棋:当走错棋的时候可以悔棋。

d、信息提示:提示当前信息状态。

e、简单的帮助文档:象棋规则介绍、软件的简单介绍和编制说明关键词:java、中国象棋对弈系统2正文:一程序设计说明1.1程序的设计及实现本系统主要有以下4个模块,每个模块对应一个程序包:1、engine:搜索引擎包,系统的核心部分。

2、message:网络对战过程中各种消息及其传递机制的类实现包。

3、main:主界面实现包。

4、pieces:棋子及其相关类实现包。

现就各个包中的要点给与说明。

1.1.1 搜索引擎的实现(engine包)(1) BitBoard.java:位棋盘的实现,见2.4节。

(2) CCEvalue.java:评价函数知识类。

本程序使用开源软件“梦入神蛋”的快速评价函数。

该函数包含子力价值和棋子所在位置的奖励值。

子力价值分别是:帅-0, 仕- 40, 象-40, 马-88, 车-200, 炮-96, 兵-9。

帅是无价的,用0表示。

以马为例,位置的奖励值如下:0,-3,5,4,2,2,5,4,2,2,-3,2,4,6,10,12,20,10,8,2,2,4,6,10,13,11,12,11,15,2,0,5,7,7,14,15,19,15,9,8,2,-10,4,10,15,16,12,11,6,2,0,5,7,7,14,15,19,15,9,8,2,4,6,10,13,11,12,11,15,2,-3,2,4,6,10,12,20,10,8,2,0,-3,5,4,2,2,5,4,2,2上面的每行代表棋盘的一条纵线。

中国象棋人机对弈

中国象棋人机对弈

中国象棋人机对弈[摘要]文章主要是研究中国象棋的人机对弈,包括象棋的界面和引擎部分。

界面主要是方便人与电脑进行交互的可视化界面。

界面包括棋盘区、菜单项和功能按钮区。

主要实现棋子的移动、悔棋、记录棋谱、难度选择等选项功能。

引擎部分主要包括,棋子棋盘的表示即数据结构,走法的生成,局面优劣的评估即评估函数,搜索算法及其优化和改进。

界面的设计是采用MFC的框架来实现界面部分,MFC是微软公司提供的一个类库,以C++类的形式封装了Windows的API,并且包含一个应用程序框架,以减少应用程序开发人员的工作量,其中包含大量的Windows句柄封装类和很多Windows控件和组件的封装类。

象棋对弈其实是一种博弈。

双人对弈,轮流走步;信息完备,双方得到的信息都是一样的;零和,即对一方有利的棋,对另一方肯定是不利的,不存在对双方均有利或无利的棋。

如果轮到自己落子的时候,一定会选择使局面分数最高的着法,如果轮到对手落子,他一定会选择使你得分最低的局面。

这就是我们经常听到的极大极小值搜索,而对局面进行估分的函数就是评估函数。

[主题词]博弈树;极大极小值搜索;alpha-beta剪枝;评估函数Chinese chess computer gameNetwork Engineering[Abstract]This paper mainly explores the Chinese chess computer game,it includes user interface and game engine.UI is a visual interface which helps human to communicate with computer.UI includes the board area,the menu and commonly used buttons.Its functions include pieces move,undoing,saving game record,choosing level and so on.The game engine mainly includes the form of pieces and board,that is data structure,move generaion,evaluation function,search algorithm.The UI is implemented through MFC.MFC is a class library provided by Microsoft.It encapsulates a Windows API in the form of c++ class,and includes a application framework,and reduces the workload of programmers.Chinese chess is a zero-sum game.Two people play,take turns to move piece;Information is the same to the both sides.There is no favorable or bad situation for both parties.If it is your turn,you will choose the favorable situation,in the same way,the opponent will choose the bad situation for you.This thought is called minimax algorithm,the function for estimating is called evaluation function.[Key Words]Game Tree;Minimax Search;Alpha-Beta Pruning;Evaluation Function目录1.综述 (1)1.1选题的意义 (1)1.2国内外研究现状概述 (1)1.3主要研究内容 (2)2.数据结构 (4)2.1棋盘的表示 (4)2.2棋子的表示 (5)3.棋子的走法 (7)4.评估函数 (8)5.搜索算法 (10)5.1极大极小值搜索算法 (10)5.2 alpha-beta剪枝算法 (12)5.3 alpha-beta剪枝算法的改进 (13)6.界面的实现 (15)6.1棋盘区 (15)6.2菜单项的设计 (16)6.3常用按钮的设计 (17)7.开局库 (18)8.系统的实现 (19)9.总结 (26)参考文献 (27)声明 (28)致谢 (29)1.综述1.1选题的意义中国象棋在中国拥有悠久的历史,这个游戏需要两个人进行对弈。

java课程设计中国象棋

java课程设计中国象棋

象棋程序设计1.课程设计目的Java语言是当今流行的网络编程语言,它具有面向对象、跨平台、分布应用等特点。

面向对象的开发方法是当今世界最流行的开发方法,它不仅具有更贴近自然的语义,而且有利于软件的维护和继承,很好的融合了“面向对象”、“跨平台”和“编程简洁”等特性。

随着Java语言的不断发展,它的应用前景将更为宽阔。

本课程设计主要是使用Swing这个Java自带的图形开发工具实现中国象棋棋子及棋盘的绘制,并根据相应的象棋规则,实现在电脑上虚拟出可以供两个人对弈的象棋游戏,从而达到了进一步巩固课堂上所学到的知识,深刻把握Java语言的重要概念及其面向对象的特性,熟练的应用面向对象的思想和设计方法解决实际问题的能力的目的。

2.设计方案论证2.1程序功能象棋是中国一种流传十分广泛的游戏。

下棋双方根据自己对棋局形式的理解和对棋艺规律的掌握,调动车马,组织兵力,协调作战在棋盘--这块特定的战场上进行着象征性的军事战斗。

本程序的功能就是将棋盘和棋子在电脑上模拟出来,双方可以通过鼠标对己方棋子的操作进行对弈。

2.2设计思路象棋,人人会走,把己方的棋子按不同棋子的规则放在棋盘合适的位置上。

象棋包含三个要素:棋盘、棋子和规则。

在本象棋程序的设计上,也大致遵循这三个要素,但是细化为四个方面:棋盘、棋盘上可以走棋的落子点、棋子和象棋规则。

棋盘其实就是一张棋盘的图形,我们要在计算机上的棋盘上落子并不像在现实生活中那么容易,这里说的棋盘充其量只是背景,真正落子的地方必须是我们在图形界面上设定的落子点,不同棋子只能按照各自的规则在这些设定的位置上摆放、搏杀。

2.3设计方法根据前面的细化,程序中分别设计了四个类对应棋盘、落子点、棋子和象棋规则这四个方面。

四个类几乎包括了程序的全部,程序框图如下图所示:图1 程序功能框图2.4详细设计 2.4.1棋子类ChessSwing 中并没有棋子这个组建类,所以我们必须设计一个组件,棋子其实就是圆形 的JLabel ,但Swing 中的JLabel 组件是方形的,没关系,利用JLabel 我们可以创建 圆形的JLabel 组件——Chess 。

中国象棋双人远程对弈

中国象棋双人远程对弈

中国象棋双人远程对弈—需求规格说明书1.引言1.1编写目的如今越来越多的人都渐渐地离中国经典棋牌类游戏——象棋远去,借此书17章的课题,我们小组为“中国象棋双人远程对弈”程序编写需求分析,借此重拾对中国文化的信心。

本说明书的预期读者为业务或需求分析人员,测试人员,用户文档编写者,项目管理人员。

1.2项目背景随着网络技术的不断发展和普及,网络游戏也有了长足的发展,网络棋牌类游戏作为其中的一分支,也备受瞩目,通过网络,人们可以在更大的范围内和他人对弈,可以增强棋艺的技术文化交流,也可以增加玩家自身水平,其中象棋作为中国经典的棋牌类游戏,魅力不可小觑。

通过以上简单分析,为了满足长远对弈的需求,“中国象棋双人网上对弈”有了开发的必要,在这样的背景下,我们小组计划开发一款这样的象棋软件。

以下是对该软件的需求规格说明。

1.3定义P2P:端对端模式端到端模式的特别是两个客户端程序直接通过网络相互连通进行游戏,参于中国象棋对弈的玩家只有两人。

这时客户端程序也可以作为服务端,具体操作如下:a.选择游戏模式为点对点模式。

b.作为客户端的一方点击连接按钮在弹出的对话框中输入对方的IP地址进行连接。

c.作为服务器的一方会监听客户端的连接请求,并对来到的请求进行响应。

d.待服务端用户同意连接请求后,双方中的任意一方都可以点击开始按钮进行游戏,点击开始游戏的一方为红方。

e.游戏过程中可以悔棋、求和和认输等操作,同时程序自动判断胜负。

C/S:服务器模式服务器模式的特别是所有的游戏玩家都集中连接服务器,在统一的平台下集中游戏。

在连接好服务器之后可以在房间里选择空位,棋桌的另一方如果也有玩家占位,则可以进行游戏。

功能简述如下:a.选择服务器模式。

b.正常运行服务器程序。

c.客户端点击连接,填入服务器所在的地址,连接成功点击显示房间。

d.双击一个空位准备游戏。

e.待对面的位置有玩家入坐就可以开始游戏,过程同端到端模式。

31.4参考资料《软件工程原理与应用》,曾强聪,赵歆编著,清华大学出版社2.系统概述2.1系统定义(目标)开发双人对弈中国象棋,实现双人远程对弈功能,并且软件界面友好,操作方便。

象棋的规则和玩法

象棋的规则和玩法

象棋的规则和玩法象棋是一种两人对弈的策略性棋类游戏,每一方有16个棋子,分别是1个国王、1个皇后、2个车、2个马、2个象(或称为象)、2个士、8个兵。

游戏目标是将对方的国王“将死”。

以下是象棋的基本规则和玩法:棋盘布局:•棋盘是8×8的方格,每个方格上都有一枚棋子。

•棋盘上有黑白两色的方块,所有棋子的初始位置在各自颜色的方块上。

棋子及其移动方式:1. 国王(King):•移动一步,可以朝任意方向(水平、垂直、对角线)移动。

2. 皇后(Queen):•可以沿着水平、垂直、对角线方向移动任意格数。

3. 车(Rook):•可以沿着水平或垂直方向移动任意格数。

4. 马(Knight):•移动方式类似“日”字,即横向或纵向移动两格,再垂直或水平移动一格。

5. 象(Bishop):•可以沿对角线移动任意格数。

6. 士(Pawn):•移动方式相对复杂:•只能向前移动一格,但在初始位置可以选择向前移动一格或两格;•吃子时是沿对角线前进。

特殊规则:1. 将军(Check):•当一方的国王被对方的棋子直接威胁到时,该国王处于“将军”状态。

2. 将死(Checkmate):•当一方的国王被对方将军,并且没有任何合法的移动可以解除将军状态时,该方被判负。

3. 平局(Stalemate):•当一方没有任何合法的移动,并且没有被将军时,游戏结束为平局。

4. 升变(Pawn Promotion):•兵成功横跨整个棋盘后,可以升变为皇后、车、马或象,玩家可以选择。

象棋是一种充满策略和深思熟虑的游戏,因此对于初学者来说,最好从基本规则和棋子的移动开始,逐渐学习各种战术和开局。

下象棋的规则

下象棋的规则

下象棋的规则1. 简介象棋,又称中国象棋,是一种两人对弈的棋类游戏。

它起源于中国,是中国传统文化的重要组成部分,也是中国象征性的游戏之一。

象棋棋盘由格线交叉而成,棋子上刻有字形和代表棋种的图案,可以在棋盘上移动和攻击对方的棋子。

下象棋是一种思维对决的游戏,需要玩家发挥战略和计划能力。

2. 棋盘和棋子下象棋使用的是一个由纵横交织而成的棋盘,棋盘上有十个横线和九个竖线,共计九十个交叉点。

棋盘分为红方和黑方两个区域,红方在上,黑方在下。

象棋棋盘象棋棋盘象棋共有32个棋子,16个红方棋子,16个黑方棋子。

红方棋子的背面为红色,黑方棋子的背面为黑色。

下面是各个棋子的名称和数量:•将(帅):1枚•士(仕):2枚•象(相):2枚•马:2匹•车(俗称车):2辆•炮:2门•兵(卒):5个3. 移动规则每个棋子的移动规则各不相同,下面是各个棋子的移动规则:3.1 将(帅)将的移动方式是在九宫格内且只能直线移动一个格子,不得出九宫格。

3.2 士(仕)士的移动方式是在己方九宫格内,可以走斜线,每步只能移动一个格子。

3.3 象(相)象的移动方式是在己方半边棋盘内,每步只能沿斜线前进两个格子,不得越子。

3.4 马马的移动方式是走日字,即先直走一个格子,然后向左或右跳一个格子,在往前走一个格子。

3.5 车(俗称车)车的移动方式是可以直线走,可以横向或纵向移动任意格数。

3.6 炮炮的移动方式是可以直线走,可以横向或纵向移动任意格数,但是要跳过一个棋子去吃对方的棋子。

3.7 兵(卒)兵的移动方式是只能向前走,每步只能移动一个格子,兵过河后可以横向移动。

4. 吃子规则在象棋中,吃子是关键的一部分。

下面是各个棋子的吃子规则:•将(帅):将帅不能直接对杀,即红方的将不能吃红方的将,黑方的帅不能吃黑方的帅。

除此之外,将帅可以吃对方的所有其他棋子。

•士(仕)、象(相):士和象可以吃对方的其他棋子,移动方式与上述移动规则一致。

•马:马在移动的过程中,如果跳过一个敌方棋子,可以吃掉敌方的这个棋子。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

// Sample 10-4: 中国象棋程序#include <afxwin.h>// 棋盘类class CPlate{int m_ndx; // 棋盘格宽int m_ndy; // 棋盘格高int m_nLeft; // 棋盘位置int m_nTop;int m_nRight;int m_nBottom;public:CPlate();void ShowPlate(CDC *pDC);void DrawConer(CDC *pDC, int row, int col, int type);CPoint GetPosition(int col, int row);};// 棋盘类的成员函数// 构造函数: 初始化CPlate::CPlate(){m_ndx = 50;m_ndy = 45;m_nLeft = 198;m_nTop = 30;m_nRight = m_nLeft+m_ndx*8;m_nBottom = m_nTop+m_ndy*9;}// 显示棋盘void CPlate::ShowPlate(CDC *pDC){// 画棋盘方格CPen penRed2(PS_SOLID,2,RGB(255,0,0));CPen *pOldPen = pDC->SelectObject(&penRed2);for(int i=0; i<10; i++){pDC->MoveTo(m_nLeft, m_nTop+i*m_ndy);pDC->LineTo(m_nRight, m_nTop+i*m_ndy);}for(i=0; i<9; i++){if(i==0 || i==8){pDC->MoveTo(m_nLeft+i*m_ndx, m_nTop);pDC->LineTo(m_nLeft+i*m_ndx, m_nBottom);}else{pDC->MoveTo(m_nLeft+i*m_ndx, m_nTop);pDC->LineTo(m_nLeft+i*m_ndx, m_nTop+4*m_ndy);pDC->MoveTo(m_nLeft+i*m_ndx, m_nTop+5*m_ndy);pDC->LineTo(m_nLeft+i*m_ndx, m_nBottom);}}// 画棋盘斜线pDC->SelectObject(pOldPen);CPen penRed1(PS_SOLID,1,RGB(255,0,0));pOldPen = pDC->SelectObject(&penRed1);pDC->MoveTo(m_nLeft+3*m_ndx, m_nTop);pDC->LineTo(m_nLeft+5*m_ndx, m_nTop+2*m_ndy);pDC->MoveTo(m_nLeft+3*m_ndx, m_nTop+2*m_ndy);pDC->LineTo(m_nLeft+5*m_ndx, m_nTop);pDC->MoveTo(m_nLeft+3*m_ndx, m_nBottom);pDC->LineTo(m_nLeft+5*m_ndx, m_nBottom-2*m_ndy);pDC->MoveTo(m_nLeft+3*m_ndx, m_nBottom-2*m_ndy);pDC->LineTo(m_nLeft+5*m_ndx, m_nBottom);pDC->SelectObject(pOldPen);// 画兵, 炮位标记DrawConer(pDC, 2, 1, 0);DrawConer(pDC, 2, 7, 0);DrawConer(pDC, 3, 0, 1);DrawConer(pDC, 3, 2, 0);DrawConer(pDC, 3, 4, 0);DrawConer(pDC, 3, 6, 0);DrawConer(pDC, 3, 8, 2);DrawConer(pDC, 7, 1, 0);DrawConer(pDC, 7, 7, 0);DrawConer(pDC, 6, 0, 1);DrawConer(pDC, 6, 2, 0);DrawConer(pDC, 6, 4, 0);DrawConer(pDC, 6, 6, 0);DrawConer(pDC, 6, 8, 2);}// 绘制兵, 炮位标志void CPlate::DrawConer(CDC *pDC, int row, int col, int type) {CPen penRed1(PS_SOLID,1,RGB(255,0,0));CPen *pOldPen = pDC->SelectObject(&penRed1);if(type == 0 || type == 1){pDC->MoveTo(m_nLeft+col*m_ndx+ 3, m_nTop+row*m_ndy-10);pDC->LineTo(m_nLeft+col*m_ndx+ 3, m_nTop+row*m_ndy-3);pDC->LineTo(m_nLeft+col*m_ndx+10, m_nTop+row*m_ndy-3);pDC->MoveTo(m_nLeft+col*m_ndx+ 3, m_nTop+row*m_ndy+10);pDC->LineTo(m_nLeft+col*m_ndx+ 3, m_nTop+row*m_ndy+3);pDC->LineTo(m_nLeft+col*m_ndx+10, m_nTop+row*m_ndy+3);}if(type == 0 || type == 2){pDC->MoveTo(m_nLeft+col*m_ndx- 3, m_nTop+row*m_ndy-10);pDC->LineTo(m_nLeft+col*m_ndx- 3, m_nTop+row*m_ndy-3);pDC->LineTo(m_nLeft+col*m_ndx-10, m_nTop+row*m_ndy-3);pDC->MoveTo(m_nLeft+col*m_ndx- 3, m_nTop+row*m_ndy+10);pDC->LineTo(m_nLeft+col*m_ndx- 3, m_nTop+row*m_ndy+3);pDC->LineTo(m_nLeft+col*m_ndx-10, m_nTop+row*m_ndy+3);}pDC->SelectObject(pOldPen);}// 取棋盘上各交叉点的坐标CPoint CPlate::GetPosition(int col, int row){CPoint point;point.x = m_nLeft+col*m_ndx;point.y = m_nTop+row*m_ndy;return point;// 棋子类// 定义棋子名称#define BING 1#define PAO 2#define JU 3#define MA 4#define XIANG 5#define SHI 6#define JIANG 7class CStone{BOOL m_bRed; // 是否红方BOOL m_bSelected; // 是否被选择int m_nCol; // 路int m_nRow; // 行CRect m_rectStone; // 棋子包含矩形BOOL m_bShow; // 是否显示CString m_sName; // 棋子名称int m_nR; // 棋子半径int m_nType; // 棋子类型public:CStone (){}CStone (BOOL red, int col, int row, LPCSTR name, int type, CPlate &plate);void ShowStone(CDC *pDC);void MoveTo(int col, int row, CPlate &plate);CRect GetRect(){return m_rectStone;}int GetType(){return m_nType;}BOOL BeKilled(int col, int row){return m_bShow && m_nCol==col && m_nRow == row;}BOOL M ouseOnStone(CPoint point){return m_rectStone.PtInRect(point) && m_bShow;}void K illIt(){m_bShow = FALSE;}void S electStone(){m_bSelected = !m_bSelected;}};// 棋子类的成员函数// 棋子类的构造函数:初始化棋子CStone::CStone(BOOL red, int col, int row, LPCSTR name, int type, CPlate &plate)m_bShow = TRUE;m_bSelected = FALSE;m_bRed = red;m_nCol = col;m_nRow = row;m_sName = name;m_nType = type;m_nR = 23;CPoint pos = plate.GetPosition(col, row);m_rectStone = CRect(pos.x-m_nR, pos.y-m_nR, pos.x+m_nR, pos.y+m_nR); }// 显示棋子void CStone::ShowStone(CDC *pDC){if(m_bShow) // 只有未被吃掉的棋子才显示{// 准备画棋子的画笔和画刷CPen *pOldPen, penNormal(PS_SOLID, 3, RGB(120, 120, 120));CBrush *pOldBrush, brushNormal, brushSelected;brushNormal.CreateSolidBrush(RGB(255, 255, 0));brushSelected.CreateSolidBrush(RGB(127, 127, 0));pOldPen = pDC->SelectObject(&penNormal);// 被选中的棋子颜色不同if(m_bSelected)pOldBrush = pDC->SelectObject(&brushSelected);elsepOldBrush = pDC->SelectObject(&brushNormal);// 显示棋子CRect r(m_rectStone);r.left ++;r.top ++;r.right --;r.bottom--;pDC->Ellipse(r);pDC->SelectObject(pOldPen);pDC->SelectObject(pOldBrush);// 准备显示棋子名称的字体CFont *pOldFont, fontStone;fontStone.CreateFont(40, 0, 0, 0, 400, FALSE, FALSE,0, OEM_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH, "楷体");pOldFont = pDC->SelectObject(&fontStone);int tx = m_rectStone.left+6;int ty = m_rectStone.top+6;pDC->SetBkMode(TRANSPARENT);// 棋子背景均为黄色,字分红、黑两色pDC->SetTextColor(RGB(m_bRed?255:0, 0, 0));pDC->TextOut(tx, ty, m_sName);pDC->SelectObject(pOldFont);}}// 将棋子放到指定位置void CStone::MoveTo(int col, int row, CPlate &plate){m_bSelected = FALSE;m_nCol = col;m_nRow = row;CPoint pos = plate.GetPosition(col, row);m_rectStone = CRect(pos.x-m_nR, pos.y-m_nR, pos.x+m_nR, pos.y+m_nR); }// 框架窗口类class CMyWnd: public CFrameWnd{CPlate m_Plate; // 棋盘CStone m_StoneList[32]; // 棋子数组BOOL m_bRedTurn; // 轮红方下BOOL m_bSelectOne; // 已选择一棋子int m_nWhichStone; // 被选择棋子的编号CRect m_rectInfo; // 信息显示位置public:CMyWnd(){InitGame();}void InitGame();void ShowInfo(CDC *pDC);BOOL KillSelfStone(int col, int row, BOOL red);int KillEnemy(int col, int row, BOOL red);void MoveStone(CPoint point);void SelectStone(CPoint point);void Go(CPoint);BOOL MoveTo(int, int);protected:afx_msg void OnPaint();afx_msg void OnLButtonDown(UINT nFlags, CPoint point);DECLARE_MESSAGE_MAP()};// 消息映射BEGIN_MESSAGE_MAP(CMyWnd,CFrameWnd)ON_WM_PAINT()ON_WM_LBUTTONDOWN()END_MESSAGE_MAP()// 框架窗口类的成员函数// 初始化棋局void CMyWnd::InitGame(){m_bRedTurn = TRUE;m_bSelectOne = FALSE;m_rectInfo = CRect(315, 480, 515, 550);m_StoneList[ 0] = CStone(TRUE, 0, 0, "车", 3, m_Plate);m_StoneList[ 1] = CStone(TRUE, 1, 0, "马", 4, m_Plate);m_StoneList[ 2] = CStone(TRUE, 2, 0, "象", 5, m_Plate);m_StoneList[ 3] = CStone(TRUE, 3, 0, "士", 6, m_Plate);m_StoneList[ 4] = CStone(TRUE, 4, 0, "将", 7, m_Plate);m_StoneList[ 5] = CStone(TRUE, 5, 0, "士", 6, m_Plate);m_StoneList[ 6] = CStone(TRUE, 6, 0, "象", 5, m_Plate);m_StoneList[ 7] = CStone(TRUE, 7, 0, "马", 4, m_Plate);m_StoneList[ 8] = CStone(TRUE, 8, 0, "车", 3, m_Plate);m_StoneList[ 9] = CStone(TRUE, 1, 2, "炮", 2, m_Plate);m_StoneList[10] = CStone(TRUE, 7, 2, "炮", 2, m_Plate);m_StoneList[11] = CStone(TRUE, 0, 3, "兵", 1, m_Plate);m_StoneList[12] = CStone(TRUE, 2, 3, "兵", 1, m_Plate);m_StoneList[13] = CStone(TRUE, 4, 3, "兵", 1, m_Plate);m_StoneList[14] = CStone(TRUE, 6, 3, "兵", 1, m_Plate);m_StoneList[15] = CStone(TRUE, 8, 3, "兵", 1, m_Plate);m_StoneList[16] = CStone(FALSE, 0, 9, "车", 3, m_Plate);m_StoneList[17] = CStone(FALSE, 1, 9, "马", 4, m_Plate);m_StoneList[18] = CStone(FALSE, 2, 9, "相", 5, m_Plate);m_StoneList[19] = CStone(FALSE, 3, 9, "仕", 6, m_Plate);m_StoneList[20] = CStone(FALSE, 4, 9, "帅", 7, m_Plate);m_StoneList[21] = CStone(FALSE, 5, 9, "仕", 6, m_Plate);m_StoneList[22] = CStone(FALSE, 6, 9, "相", 5, m_Plate);m_StoneList[23] = CStone(FALSE, 7, 9, "马", 4, m_Plate);m_StoneList[24] = CStone(FALSE, 8, 9, "车", 3, m_Plate);m_StoneList[25] = CStone(FALSE, 1, 7, "炮", 2, m_Plate);m_StoneList[26] = CStone(FALSE, 7, 7, "炮", 2, m_Plate);m_StoneList[27] = CStone(FALSE, 0, 6, "卒", 1, m_Plate);m_StoneList[28] = CStone(FALSE, 2, 6, "卒", 1, m_Plate);m_StoneList[29] = CStone(FALSE, 4, 6, "卒", 1, m_Plate);m_StoneList[30] = CStone(FALSE, 6, 6, "卒", 1, m_Plate);m_StoneList[31] = CStone(FALSE, 8, 6, "卒", 1, m_Plate); }// 处理 WM_ONPAINT 消息, 绘制窗口客户区 (绘制棋盘, 棋子等) void CMyWnd::OnPaint(){CPaintDC dc(this);m_Plate.ShowPlate(&dc); // 显示棋盘for(int i=0; i<32; i++) // 显示所有棋子m_StoneList[i].ShowStone(&dc);ShowInfo(&dc); // 显示轮谁行棋}// 处理 WM_ONLBUTTONDOWN 消息, 移动棋子void CMyWnd::OnLButtonDown(UINT nFlags, CPoint point){if(m_bSelectOne) // 已选择了要移动的棋子MoveStone(point);else // 尚未选择要移动的棋子SelectStone(point);}// 移动棋子void CMyWnd::MoveStone(CPoint point){// 如果选择原来的棋子, 作废原来的选择if(m_StoneList[m_nWhichStone].MouseOnStone(point)){m_StoneList[m_nWhichStone].SelectStone();m_bSelectOne = FALSE;InvalidateRect(m_StoneList[m_nWhichStone].GetRect(), FALSE);}else // 在棋盘其他位置行棋Go(point);}// 走棋或吃棋void CMyWnd::Go(CPoint point){for(int col=0; col<9; col++) // 检查鼠标是否指向某个棋盘交叉点for(int row=0; row<10; row++){CPoint p = m_Plate.GetPosition(col, row);CRect r(p.x-23, p.y-23, p.x+23, p.y+23);if(r.PtInRect(point)) // 鼠标指向该交叉点{if(KillSelfStone(col, row, m_bRedTurn))MessageBox("您竟然想吃自己人?!");elsem_bRedTurn = MoveTo(col, row);}}}// 移到指定位置或吃子BOOL CMyWnd::MoveTo(int col, int row){// 更新窗口客户区原来的棋子位置InvalidateRect(m_StoneList[m_nWhichStone].GetRect());// 棋子移向新位置m_StoneList[m_nWhichStone].MoveTo(col, row, m_Plate);// 更新窗口客户区新的棋子位置InvalidateRect(m_StoneList[m_nWhichStone].GetRect());// 还原选择棋子标志m_bSelectOne = FALSE;// 检查是否吃了对方的棋子int i = KillEnemy(col, row, m_bRedTurn);if(i>=0) // 确实吃了对方棋子{m_StoneList[i].KillIt();if(m_StoneList[i].GetType() == JIANG){if(m_bRedTurn)MessageBox(m_bRedTurn?"红方胜!":"黑方胜!");InitGame();Invalidate();return TRUE;}}// 更新窗口客户区提示信息位置InvalidateRect(m_rectInfo);return !m_bRedTurn;}// 选择棋子void CMyWnd::SelectStone(CPoint point){int nwhich = m_bRedTurn?0:16;// 逐个查看己方棋子是否被选中for(int i=nwhich; i<nwhich+16; i++)if(m_StoneList[i].MouseOnStone(point)){m_StoneList[i].SelectStone();// 更新窗口客户区被选中棋子的位置(该棋子要变色)InvalidateRect(m_StoneList[i].GetRect(), FALSE);m_nWhichStone = i;m_bSelectOne = TRUE;break;}}// 显示轮谁行棋void CMyWnd::ShowInfo(CDC *pDC){CFont *pOldFont, fontInfo;fontInfo.CreateFont(50, 0, 0, 0, 400, FALSE, FALSE,0, OEM_CHARSET, OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,DEFAULT_PITCH, "楷体");pOldFont = pDC->SelectObject(&fontInfo);pDC->SetTextColor(RGB(m_bRedTurn?255:0, 0, 0));pDC->TextOut(m_rectInfo.left, m_rectInfo.top,m_bRedTurn?"红方行棋": "黑方行棋");pDC->SelectObject(pOldFont);}// 检查是否误杀己方棋子BOOL CMyWnd::KillSelfStone(int col, int row, BOOL red) {int from = red?0:16;// 逐个检查己方棋子是否被误杀for(int i=from; i<from+16; i++)if( m_StoneList[i].BeKilled(col, row))return TRUE;return FALSE;}// 检查是否吃对方棋子int CMyWnd::KillEnemy(int col, int row, BOOL red){int from = red?16:0;// 逐个检查对方棋子是否被吃for(int i=from; i<from+16; i++)if( m_StoneList[i].BeKilled(col, row))return i;return -1;}// 应用程序类class CMyApp: public CWinApp{public:BOOL I nitInstance();};// 应用程序类的实例初始化函数BOOL CMyApp::InitInstance(){CMyWnd *pFrame = new CMyWnd;pFrame->Create(0,_T("中国象棋程序"));pFrame->ShowWindow(SW_SHOWMAXIMIZED);pFrame->UpdateWindow();this->m_pMainWnd = pFrame;return TRUE;}// 应用程序类的全局对象CMyApp ThisApp;。

相关文档
最新文档