Cocos2d-X开发中国象棋《九》走棋规则

在上一节中实现了走棋,这篇博客将介绍中国象棋中的走棋规则


在写博客前先可能一下象棋的走棋规则:

1)将

将的坐标关系:横坐标相等,纵坐标相减绝对值等于1,或者纵坐标相等,横坐标相减绝对值等于1

将的特殊要求:目标坐标坐落于九宫内

将的例外情况:假设两个老将面对面而中间没有棋子阻拦。老将能够直接飞到对方九宫吃对方老将

2)士

士的坐标关系:纵坐标和横坐标相减的绝对值都是1,

士的特殊要求:目标坐标坐落于九宫内

3)象

象的坐标关系:纵坐标和横坐标相减的绝对值都是2

象的特殊要求:象眼不能有棋子,不能过河

4)车

车的坐标关系:横坐标或者纵坐标相等

车的特殊要求:两个坐标之间不能有棋子存在

5)马

马的坐标关系:横坐标相减等于1且纵坐标相减等于2,或者反过来

马的特殊要求:马腿不能憋着

6)炮

炮的坐标关系:与车同样

炮的特殊要求:假设目标坐标没有棋子,则与车一样,否则要求中间有一个棋子

7)兵

过河前:

兵的坐标关系:纵坐标相差1,并且仅仅能前进

兵的特殊要求:没有

过河后:

兵的坐标关系:纵坐标相差1或者横坐标相差1。不能后退

兵的特殊要求:没有


实现代码:

首先在在SceneGame类中定义一个成员函数canMove(int moveid, int killid, int x, int y)用于实现走棋规则

//走棋规则
bool SceneGame::canMove(int moveid, int killid, int x, int y)
{//获得选中的棋子Stone* s = _s[moveid];//棋子的类型switch(s->getType()){//将的走棋规则case Stone::JIANG:{return canMoveJiang(moveid, killid, x, y);}break;//士的走棋规则case Stone::SHI:{return canMoveShi(moveid, x, y);}break;//相的走棋规则case Stone::XIANG:{return canMoveXiang(moveid, x, y);}break;//车的走棋规则case Stone::CHE:{return canMoveChe(moveid, x, y);}break;//马的走棋规则case Stone::MA:{return canMoveMa(moveid, x, y);}break;//炮的走棋规则case Stone::PAO:{return canMovePao(moveid, killid, x, y);}break;//兵的走棋规则case Stone::BING:{return canMoveBing(moveid, x, y);}break;default:{break;}}return false;
}


然后针对不同的棋子定义成员函数。实现走棋规则

canMoveJiang(int moveid, int killid, int x, int y)实现将的走棋规则

//将的走棋规则
bool SceneGame::canMoveJiang(int moveid, int killid, int x, int y)
{Stone* skill = _s[killid];//将的走棋规则://1、一次走一格//2、不能出九宫格//CCLog("x=%d, y=%d", x, y);//CCLog("moveid=%d, killid=%d", moveid, killid);//将的对杀if(skill->getType() == Stone::JIANG){return canMoveChe(moveid, x, y);}//通过棋子的ID得到棋子Stone* s = _s[moveid];//获得将当前的位置int xo = s->getX();int yo = s->getY();//获得将走的格数//(x,y)表示将走到的位置int xoff = abs(xo - x);int yoff = abs(yo - y);int d = xoff*10 + yoff;//走将的时候有两种情况//xoff=1, yoff=0:将向左或向右//xoff=0, yoff=1:将向前或向后if(d != 1 && d != 10){return false;}//推断将是否出了九宫//红色的将和黑色的将的x坐标的范围都是3<=x<=5if(x<3 || x>5){return false;}//假设玩家的棋子是红棋if(_redSide == s->getRed()){//推断将是否出了九宫if(y<0 || y>2){return false;}}else//推断黑色的将的范围{//推断将是否出了九宫if(y>9 || y<7){return false;}}return true;
}


canMoveShi(int moveid, int x, int y)实现士的走棋规则

//士的走棋规则
bool SceneGame::canMoveShi(int moveid, int x, int y)
{//士的走棋规则://1、一次走一格//2、不能出九宫格//3、斜着走//通过棋子的ID得到棋子Stone* s = _s[moveid];//获得相走棋前的位置int xo = s->getX();int yo = s->getY();//获得相走的格数//(x,y)表示将走到的位置int xoff = abs(xo - x);int yoff = abs(yo - y);int d = xoff*10 + yoff;//士每走一步x方向走1格,y方向走1格//当走的格数大于1格时//返回falseif(d != 11){return false;}//推断士是否出了九宫//红色的士和黑色的士的x坐标的范围都是3<=x<=5if(x<3 || x>5){return false;}//假设玩家的棋子是红棋if(_redSide == s->getRed()){//推断士是否出了九宫if(y<0 || y>2){return false;}}else//推断黑色的士的范围{//推断士是否出了九宫if(y>9 || y<7){return false;}}return true;
}


canMoveXiang(int moveid, int x, int y)实现相的走棋规则

//相的走棋规则
bool SceneGame::canMoveXiang(int moveid, int x, int y)
{//相的走棋规则://每走一次x移动2格,y移动2格//不能过河//通过棋子的ID得到棋子Stone* s = _s[moveid];//获得相走棋前的位置int xo = s->getX();int yo = s->getY();//获得相走的格数//(x,y)表示将走到的位置int xoff = abs(xo - x);int yoff = abs(yo - y);int d = xoff*10 + yoff;//相每一次x方向走2格子,y方向走2格//当走的格数大于2格时//返回falseif(d != 22){return false;}//计算两个坐标的中点坐标int xm = (xo + x) / 2;int ym = (yo + y) / 2;//得到(xm,ym)上的棋子int id = getStone(xm, ym);//当(xm,ym)上有棋子的时候if(id != -1){//不能走相return false;}//限制相不能过河//假设玩家的棋子是红棋if(_redSide == s->getRed()){//推断相是否过了河if(y > 4){return false;}}else//推断黑色的相的范围{//推断相是否过了河if(y < 5){return false;}}return true;
}


canMoveChe(int moveid, int x, int y)实现车的走棋规则

//车的走棋规则
bool SceneGame::canMoveChe(int moveid, int x, int y)
{//通过棋子的ID得到棋子Stone* s = _s[moveid];//获得车走棋前的位置int xo = s->getX();int yo = s->getY();//当两点之间有棋子的时候车不能走if(getStoneCount(xo,yo,x,y) != 0){return false;}return true;
}

canMoveMa(int moveid, int x, int y)实现马的走棋规则

//马的走棋规则
bool SceneGame::canMoveMa(int moveid, int x, int y)
{//通过棋子的ID得到棋子Stone* s = _s[moveid];//获得马走棋前的位置int xo = s->getX();int yo = s->getY();//CCLog("xo=%d", xo);//CCLog("yo=%d", yo);//获得马走的格数//(x,y)表示马走到的位置//马有两种情况://第一种情况:马先向前或向后走1步,再向左或向右走2步//另外一种情况:马先向左或向右走1不,再向前或向后走2步int xoff = abs(xo-x);int yoff = abs(yo-y);//CCLog("x=%d", x);//CCLog("y=%d", y);int d = xoff*10 + yoff;//CCLog("d=%d", d);if(d != 12 && d != 21)     {return false;}int xm, ym;//记录绑脚点坐标if(d == 12)//当马走的是第一种情况{xm = xo;//绑脚点的x坐标为走棋前马的x坐标ym = (yo + y) / 2;//绑脚点的y坐标为走棋前马的y坐标和走棋后马的y坐标的中点坐标}else//当马走的是另外一种情况{xm = (xo + x) / 2;//绑脚点的x坐标为走棋前马的x坐标和走棋后马的x坐标的中点坐标ym = yo;;//绑脚点的y坐标为走棋前马的y坐标}//CCLog("xm=%d", xm);//CCLog("ym=%d", ym);//当绑脚点有棋子时,不能走if(getStone(xm, ym) != -1) {return false;}return true;
}

canMovePao(int moveid, int killid, int x, int y)实现炮的走棋规则

//炮的走棋规则
bool SceneGame::canMovePao(int moveid, int killid, int x, int y)
{//通过棋子的ID得到棋子Stone* s = _s[moveid];//获得炮走棋前的位置int xo = s->getX();int yo = s->getY();//当触摸点上有一个棋子//并且两点之间仅仅有一个棋子的时候//炮吃掉触摸点上的棋子if(killid != -1 && this->getStoneCount(xo,yo,x,y) == 1){return true;}if(killid == -1 && this->getStoneCount(xo, yo, x, y) == 0) {return true;}return false;
}


canMoveBing(int moveid, int x, int y)实现兵的走棋规则

//兵的走棋规则
bool SceneGame::canMoveBing(int moveid, int x, int y)
{//兵的走棋规则://1、一次走一格//2、前进一格后不能后退//3、过河后才干够左右移动//通过棋子的ID得到棋子Stone* s = _s[moveid];//获得将当前的位置int xo = s->getX();int yo = s->getY();//获得兵走的格数//(x,y)表示将走到的位置int xoff = abs(xo - x);int yoff = abs(yo - y);int d = xoff*10 + yoff;//走将的时候有两种情况//xoff=1, yoff=0:将向左或向右//xoff=0, yoff=1:将向前或向后if(d != 1 && d != 10){return false;}//假设玩家的棋子是红棋if(_redSide == s->getRed()){//限制红色的兵不能后退if(y < yo){return false;}//红色的兵没有过河不能左右移动if(yo <= 4 && y == yo){return false;}}else//推断黑色的兵{//限制黑色的兵不能后退if(y > yo){return false;}//黑色的兵没有过河不能左右移动if(yo >= 5 && y == yo){return false;}}return true;
}


getStoneCount(int xo, int yo, int x, int y)推断两个棋子之间棋子的个数,用于车和炮以及将的对杀

///计算(xo,yo)和(x,y)之间的棋子数
//假设棋子数为-1,表示(xo,yo)和(x,y)不在一条直线上
int SceneGame::getStoneCount(int xo, int yo, int x, int y)
{int ret = 0;//记录两点之间的棋子的个数//(xo,yo)和(x,y)不在同一条直线上if(xo != x && yo != y){return -1;}//(xo,yo)和(x,y)在同一点上if(xo == x && yo == y){return -1;}//两点在同一条竖线上if(xo == x){//min为两个点中y坐标最小的点的y坐标int min = yo < y ?

yo : y; //max为两个点中y坐标最大的点的y坐标 int max = yo > y ? yo : y; //查找同一条竖线上两点之间的棋子数 for(int yy=min+1; yy<max; yy++) { //当两点之间有棋子的时候 if(getStone(x,yy) != -1) { ++ret;//棋子数加1 } } } else//两点在同一条横线上yo == y { //min为两个点中x坐标最小的点的x坐标 int min = xo < x ? xo : x; //max为两个点中x坐标最大的点的x坐标 int max = xo > x ? xo : x; //查找同一条竖线上两点之间的棋子数 for(int xx=min+1; xx<max; xx++) { //当两点之间有棋子的时候 if(getStone(xx,y) != -1) { ++ret;//棋子数加1 } } } //返回两点之间的棋子数 return ret; }


參考文章:http://blog.csdn.net/itcastcpp/article/details/17673393



转载于:https://www.cnblogs.com/jzssuanfa/p/7270587.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/428998.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php代码expl,php – 参数号无效:参数未定义Explination

我使用一个简单的测试表来尝试调试此错误.我试着写一个脚本,用户可以更新他们的用户信息,我搜索过但没有找到任何具体的帮助我.我的测试代码如下&#xff1a;PHPif(isset($_POST[submitBtn])){//Display Errors{{ PDO::ATTR_ERRMODE; }}$db->setAttribute( PDO::ATTR_ERRMOD…

js学习总结----编写简单的ajax方法库

具体代码如下: ~function(){//ajax:实现ajax请求的公共方法;当一个方法传递的参数过多&#xff0c;而且还不固定&#xff0c;我们使用对象统一传值法&#xff08;把需要传递的参数值都放在一个对象中&#xff0c;一起传递进去即可&#xff09;function ajax(options){//把需要使…

netlify支持php吗,hexo netlify 搭建简易博客

npm install hexo-cli -ghexo init blogcd blognpm installhexo server将本地文件夹推送到github修改主题git clone https://github.com/jangdelong/hexo-theme-xups.git themes/xups themes/xups修改yml配置文件重新hexo server自己的博客sleepy-poincare-e0ca11.netlify.c…

jps、jstack、jmap、jhat、jstat、hprof使用详解

https://my.oschina.net/feichexia/blog/196575#comment-list A、 jps(Java Virtual Machine Process Status Tool) jps主要用来输出JVM中运行的进程状态信息。语法格式如下&#xff1a; 如果不指定hostid就默认为当前主机或服务器。 命令行参数选项说明如下&#xff1a;…

oracle数据库日期格式的运算,Oracle时间类型date,timestamp时间差计算

Oracle的时间类型有两种date和timestamp. date精确到秒,timestamp精确到毫秒.1.计算date类型的时间差可以先把年,月,日,小时,分,秒用to_char函数拆分出来,再用to_number函数转换成数值类型.有了这些单独分开的时间就好办了.就再一个个的去减,记得考虑单位换算就行.比如都转换…

pta乙级之路

1017 A除以B (20分) #include #include #include<math.h> using namespace std; int main() { string str; cin>>str; int n,ch[1009]; cin>>n; int lenstr.length(); for (int i0;i<len;i){ ch[i]str[i]-‘0’; } for (int i0;i<len-1;i){ ch[i1]10*(…

oracle禁止修改密码,Oracle 用户密码过期后不允许修改密码的示例代码

--本人是初学者&#xff0c;不知道还有没有更好的方法create table PASSWD_CHANGED(USER_NAME VARCHAR2(20),OLD_PASSWD VARCHAR2(100),NEW_PASSWD VARCHAR2(100))CREATE OR REPLACE FUNCTION my_password_verify(usernameVARCHAR2,passwordVARCHAR2,old_passwordVARCHAR2)RETU…

查看网关

简单记两个 [rootoracle ~]# ip route show default via 192.0.2.2 dev eth0 proto static 192.0.2.0/24 dev eth0 proto kernel scope link src 192.0.2.110 metric 1 [rootoracle ~]# route -n Kernel IP routing table Destination Gateway Genmask …

double的四舍五入和上下取整

在头文件中有math。 向上取整&#xff1a;ceil(double x); 向下取整&#xff1a;floor(double x); 四舍五入&#xff1a;round(double); 特别注意&#xff1a;在C语言中上面的三个函数返回的是double型的。 但是&#xff1a; #include<iostream> #include<cmath> …

url去除掉一个参数php,php怎样去掉url中的参数_后端开发

php去掉url中的参数的要领是&#xff1a;能够经由过程trim()函数来完成。该函数能够删除字符串中的指定字符&#xff0c;并返回已修正的字符串。细致使用要领如&#xff1a;【trim($url,"?");trim($url,"#");】。相干函数引见&#xff1a;(引荐教程&#…

C++之类的静态成员变量和静态成员函数

static静态成员函数 在类中。static 除了声明静态成员变量&#xff0c;还能够声明静态成员函数。普通成员函数能够訪问全部成员变量。而静态成员函数仅仅能訪问静态成员变量。我们知道。当调用一个对象的成员函数&#xff08;非静态成员函数&#xff09;时&#xff0c;系统会把…

Oracle杀事务数据库崩溃,关于pl/sql dev窗口崩溃导致锁表

今天在用pl/sql dev写sql的时候&#xff0c;刚刚写到一个select XXX from table for update,打开了锁的按钮&#xff0c;进行了数据修改&#xff0c;这个时候没有commit&#xff0c;因为临时有事&#xff0c;所以先出去一会&#xff0c;半个小时回来后&#xff0c;发现点击pl/s…

使用VS Code开发.Net Core 2.0 MVC Web应用程序教程之一

好吧&#xff0c;现在我们假设你已经安装好了VS Code开发工具、.Net Core 2.0预览版的SDK dotnet-sdk-2.0.0&#xff08;注意自己的操作系统&#xff09;&#xff0c;并且已经为VS Code安装好了C#扩展&#xff08;在VS Code的扩展菜单中输入OmniSharp&#xff0c;安装扩展即可&…

oracle12 扩充表空间,oracle查询及扩充表空间

查询表空间目录及是否自动扩展select file_id,file_name,tablespace_name,autoextensible,increment_by from dba_data_files order by file_id desc;总的表空间情况select substr(a.tablespace_name,1,15) tablespacename,sum(a.bytes/1024/1024) as "totle_size(M)"…

WPF--TextBlock的ToolTip附加属性

大家可能在项目中&#xff0c;有的时候&#xff0c;由于显示的内容过长&#xff0c;所以&#xff0c;需要显示一部分内容&#xff0c;然后后面用省略号&#xff0c;把鼠标放上去&#xff0c;会显示出来全部的内容。 作为一个LowB程序员的我&#xff0c;第一反应是SubString截取…

L2-001 紧急救援 (25 分)

L2-001 紧急救援 (25 分)作为一个城市的应急救援队伍的负责人&#xff0c;你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候&#x…

oracle 虚拟补丁,趋势科技虚拟补丁(Virtual Patch)

本帖最后由 vger520 于 2012-4-26 09:20 编辑预先防止漏洞遭到攻击Virtual Patch(虚拟补丁)实际案例微软最近紧急通知系统管理员立即安装一个影响所有 Windows 系统的重大安全更新&#xff1a;「MS12-020远程桌面的漏洞可能会允许远端执行程序码」。而趋势科技的客户在该漏洞发…

Laravel框架一:原理机制篇

转载自http://www.cnblogs.com/XiongMaoMengNan/p/6644892.htmlLaravel作为在国内国外都颇为流行的PHP框架&#xff0c;风格优雅&#xff0c;其拥有自己的一些特点。 一. 请求周期 Laravel 采用了单一入口模式&#xff0c;应用的所有请求入口都是 public/index.php 文件。 注册…

L2-002 链表去重 (25 分) 船新方法

L2-002 链表去重 (25 分)给定一个带整数键值的链表 L&#xff0c;你需要把其中绝对值重复的键值结点删掉。即对每个键值 K&#xff0c;只有第一个绝对值等于 K 的结点被保留。同时&#xff0c;所有被删除的结点须被保存在另一个链表上。例如给定 L 为 21→-15→-15→-7→15&…

oracle中间键配置,Oracle Exalogic中间件云服务器简介及产品配置特点(2)

Oracle Exalogic中间件云服务器 —— 软硬件结合的优化平台目前&#xff0c;企业所面临的应用挑战大多集中在异构环境、复杂的多层应用以及现有环境的低利用率等。于是&#xff0c;企业开始根据实际业务需求和投资情况将系统进行整合设计&#xff0c;旨在精简架构以提高系统的灵…